Skip to content

Commit d4e69f1

Browse files
authored
fix: endless loop in utf8_len while input is an invalid utf8 string (#62)
1 parent ed96a2c commit d4e69f1

File tree

4 files changed

+97
-23
lines changed

4 files changed

+97
-23
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@ jobs:
1717
uses: actions/checkout@v2
1818
with:
1919
submodules: recursive
20-
- name: Linux Get dependencies
21-
run: |
22-
sudo apt install -y build-essential libncurses5-dev libreadline-dev libssl-dev perl lua5.1 liblua5.1-0-dev
23-
curl -fsSL https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh | sh
2420

25-
- name: Linux Before install
26-
run: |
27-
sudo luarocks install luacheck
21+
- name: Setup Lua
22+
uses: leafo/[email protected]
23+
with:
24+
luaVersion: "5.1.5"
25+
26+
- name: Setup Luarocks
27+
uses: leafo/gh-actions-luarocks@v4
28+
with:
29+
luarocksVersion: "3.8.0"
30+
31+
- name: Linux Get dependencies
32+
run: sudo apt install -y build-essential libncurses5-dev libreadline-dev libssl-dev perl
2833

2934
- name: Linux Install
3035
run: |
@@ -36,6 +41,6 @@ jobs:
3641
3742
- name: Linux Script
3843
run: |
39-
sudo luarocks install rockspec/jsonschema-master-0.rockspec
44+
luarocks make rockspec/jsonschema-master-0.rockspec
4045
export PATH=$OPENRESTY_PREFIX/nginx/sbin:$PATH
4146
make test

Makefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
OR_EXEC ?= $(shell which openresty)
22
LUA_JIT_DIR ?= $(shell ${OR_EXEC} -V 2>&1 | grep prefix | grep -Eo 'prefix=(.*)/nginx\s+--' | grep -Eo '/.*/')luajit
33
LUAROCKS_VER ?= $(shell luarocks --version | grep -E -o "luarocks [0-9]+.")
4-
LUA_PATH ?= "./lib/?.lua;./deps/lib/lua/5.1/?.lua;./deps/share/lua/5.1/?.lua;;"
5-
LUA_CPATH ?= "./deps/lib/lua/5.1/?.so;;"
4+
LUA_PATH ?= ./lib/?.lua;./deps/lib/lua/5.1/?.lua;./deps/share/lua/5.1/?.lua;;
5+
LUA_CPATH ?= ./deps/lib/lua/5.1/?.so;;
66

77

88
### help: Show Makefile rules.
@@ -27,11 +27,11 @@ endif
2727

2828
### test: Run the test case
2929
test:
30-
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft4.lua
31-
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft6.lua
32-
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft7.lua
33-
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/default.lua
34-
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/200more_variables.lua
30+
LUA_PATH="$(LUA_PATH)" LUA_CPATH="$(LUA_CPATH)" resty t/draft4.lua
31+
LUA_PATH="$(LUA_PATH)" LUA_CPATH="$(LUA_CPATH)" resty t/draft6.lua
32+
LUA_PATH="$(LUA_PATH)" LUA_CPATH="$(LUA_CPATH)" resty t/draft7.lua
33+
LUA_PATH="$(LUA_PATH)" LUA_CPATH="$(LUA_CPATH)" resty t/default.lua
34+
LUA_PATH="$(LUA_PATH)" LUA_CPATH="$(LUA_CPATH)" resty t/200more_variables.lua
3535

3636

3737
### clean: Clean the test case

lib/jsonschema.lua

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -369,17 +369,60 @@ function validatorlib.tablekind(t)
369369
return 0 -- mixed array/object
370370
end
371371

372-
function validatorlib.utf8_len(s)
373-
local c, j=0, 1
374-
while j <= #s do
375-
local cb = str_byte(s, j)
376-
if cb >= 0 and cb <= 127 then j = j + 1
377-
elseif cb >= 192 and cb <= 223 then j = j + 2
378-
elseif cb >= 224 and cb <= 239 then j = j + 3
379-
elseif cb >= 240 and cb <= 247 then j = j + 4
372+
373+
local accept_range = {
374+
{lo = 0x80, hi = 0xBF},
375+
{lo = 0xA0, hi = 0xBF},
376+
{lo = 0x80, hi = 0x9F},
377+
{lo = 0x90, hi = 0xBF},
378+
{lo = 0x80, hi = 0x8F}
379+
}
380+
381+
function validatorlib.utf8_len(str)
382+
local i, n, c = 1, #str, 0
383+
local first, byte, left_size, range_idx
384+
385+
while i <= n do
386+
first = str_byte(str, i)
387+
if first >= 0x80 and first <= 0xF4 then
388+
left_size = 0
389+
range_idx = 1
390+
if first >= 0xC2 and first <= 0xDF then --2 bytes
391+
left_size = 1
392+
elseif first >= 0xE0 and first <= 0xEF then --3 bytes
393+
left_size = 2
394+
if first == 0xE0 then
395+
range_idx = 2
396+
elseif first == 0xED then
397+
range_idx = 3
398+
end
399+
elseif first >= 0xF0 and first <= 0xF4 then --4 bytes
400+
left_size = 3
401+
if first == 0xF0 then
402+
range_idx = 4
403+
elseif first == 0xF4 then
404+
range_idx = 5
405+
end
406+
end
407+
408+
if i + left_size > n then --invalid
409+
left_size = 0
410+
end
411+
412+
for j = 1, left_size do
413+
byte = str_byte(str, i + j)
414+
if byte < accept_range[range_idx].lo or byte > accept_range[range_idx].hi then --invalid
415+
left_size = 0
416+
break
417+
end
418+
range_idx = 1
419+
end
420+
i = i + left_size
380421
end
422+
i = i + 1
381423
c = c + 1
382424
end
425+
383426
return c
384427
end
385428

t/default.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,29 @@ local t = {
187187
local ok = validator(t)
188188
assert(ok~=nil, "fail: failed to negative check of int64")
189189
ngx.say("passed: pass negative check of int64")
190+
191+
----------------------------------------------------- test case 7
192+
-- check string len
193+
-- issue #61
194+
local cases = {
195+
{"abcd", 4},
196+
{"☺☻☹", 3},
197+
{"1,2,3,4", 7},
198+
{"\xff", 1},
199+
{"\xc2\x80", 1},
200+
{"\xe0\x00", 2},
201+
{"\xe2\x80a", 3},
202+
{"\xed\x80\x80", 1},
203+
{"\xf0\x80", 2},
204+
{"\xf4\x80", 2},
205+
}
206+
207+
local schema = {}
208+
for i, case in ipairs(cases) do
209+
schema.minLength = case[2]
210+
schema.maxLength = case[2]
211+
local validator = jsonschema.generate_validator(schema)
212+
local ok, err = validator(case[1])
213+
assert(ok, string.format("fail: validate case %d, err: %s, ", i, err))
214+
end
215+
ngx.say("passed: check string len")

0 commit comments

Comments
 (0)