@@ -395,6 +395,22 @@ local function to_lua_code(var)
395395 return code .. " }"
396396end
397397
398+ local function utf8_len_func (ctx )
399+ return sformat ([[ function(s)
400+ local c, j=0, 1
401+ while j <= #s do
402+ local cb = %s(s, j)
403+ if cb >= 0 and cb <= 127 then j = j + 1
404+ elseif cb >= 192 and cb <= 223 then j = j + 2
405+ elseif cb >= 224 and cb <= 239 then j = j + 3
406+ elseif cb >= 240 and cb <= 247 then j = j + 4
407+ end
408+ c = c + 1
409+ end
410+ return c
411+ end]] , ctx :libfunc (" string.byte" ))
412+ end
413+
398414generate_validator = function (ctx , schema )
399415 -- get type informations as they will be necessary anyway
400416 local datatype = ctx :localvar (sformat (' %s(%s)' ,
@@ -747,15 +763,19 @@ generate_validator = function(ctx, schema)
747763 if schema .minLength or schema .maxLength or schema .pattern then
748764 ctx :stmt (sformat (' if %s == "string" then' , datatype ))
749765 if schema .minLength then
750- ctx :stmt (sformat (' if #%s < %d then' , ctx :param (1 ), schema .minLength ))
751- ctx :stmt (sformat (' return false, %s("string too short, expected at least %d, got %%d", #%s)' ,
752- ctx :libfunc (' string.format' ), schema .minLength , ctx :param (1 )))
766+ ctx :stmt (sformat (' local utf8_len_func = %s' , utf8_len_func (ctx )))
767+ ctx :stmt (sformat (' local c = utf8_len_func(%s)' ,ctx :param (1 )))
768+ ctx :stmt (sformat (' if c < %d then' , schema .minLength ))
769+ ctx :stmt (sformat (' return false, %s("string too short, expected at least %d, got ") ..c' ,
770+ ctx :libfunc (' string.format' ), schema .minLength ))
753771 ctx :stmt ( ' end' )
754772 end
755773 if schema .maxLength then
756- ctx :stmt (sformat (' if #%s > %d then' , ctx :param (1 ), schema .maxLength ))
757- ctx :stmt (sformat (' return false, %s("string too long, expected at most %d, got %%d", #%s)' ,
758- ctx :libfunc (' string.format' ), schema .maxLength , ctx :param (1 )))
774+ ctx :stmt (sformat (' local utf8_len_func = %s' , utf8_len_func (ctx )))
775+ ctx :stmt (sformat (' local c = utf8_len_func(%s)' ,ctx :param (1 )))
776+ ctx :stmt (sformat (' if c > %d then' , schema .maxLength ))
777+ ctx :stmt (sformat (' return false, %s("string too long, expected at most %d, got ") .. c' ,
778+ ctx :libfunc (' string.format' ), schema .maxLength ))
759779 ctx :stmt ( ' end' )
760780 end
761781 if schema .pattern then
0 commit comments