diff --git a/Makefile b/Makefile index 5a64310..7ebc585 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ test: LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft6.lua LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft7.lua LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/default.lua + LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/200more_variables.lua ### clean: Clean the test case diff --git a/lib/jsonschema.lua b/lib/jsonschema.lua index 1ab5352..239c76e 100644 --- a/lib/jsonschema.lua +++ b/lib/jsonschema.lua @@ -111,8 +111,8 @@ function codectx_mt:localvar(init, nres) local names = {} local nloc = self._nloc nres = nres or 1 - for i=1, nres do - names[i] = sformat('var_%d_%d', self._idx, nloc+i) + for i = 1, nres do + names[i] = sformat('var_%d_%d', self._idx, nloc + i) end self:stmt(sformat('local %s = ', tab_concat(names, ', ')), init or 'nil') @@ -120,6 +120,19 @@ function codectx_mt:localvar(init, nres) return unpack(names) end +function codectx_mt:localvartab(init, nres) + local names = {} + local nloc = self._nloc + nres = nres or 1 + for i = 1, nres do + names[i] = sformat('locals.var_%d_%d', self._idx, nloc + i) + end + + self:stmt(sformat('%s = ', tab_concat(names, ', ')), init or 'nil') + self._nloc = nloc + nres + return unpack(names) +end + function codectx_mt:param(n) self._nparams = mmax(n, self._nparams) return 'p_' .. n @@ -148,7 +161,7 @@ function codectx_mt:validator(path, schema) local root = self._root local var = root._validators[resolved] if not var then - var = root:localvar('nil') + var = root:localvartab('nil') root._validators[resolved] = var root:stmt(sformat('%s = ', var), generate_validator(root:child(ref), resolved)) end @@ -513,9 +526,9 @@ end generate_validator = function(ctx, schema) -- get type informations as they will be necessary anyway - local datatype = ctx:localvar(sformat('%s(%s)', + local datatype = ctx:localvartab(sformat('%s(%s)', ctx:libfunc('type'), ctx:param(1))) - local datakind = ctx:localvar(sformat('%s == "table" and %s(%s)', + local datakind = ctx:localvartab(sformat('%s == "table" and %s(%s)', datatype, ctx:libfunc('lib.tablekind'), ctx:param(1))) if type(schema) == "table" and schema._org_val ~= nil then @@ -661,7 +674,7 @@ generate_validator = function(ctx, schema) local propset, addprop_validator -- all properties defined in the object if schema.additionalProperties ~= nil and schema.additionalProperties ~= true then -- TODO: can be optimized with a static table expression - propset = ctx._root:localvar('{}') + propset = ctx._root:localvartab('{}') if schema.properties then for prop, _ in pairs(schema.properties) do ctx._root:stmt(sformat('%s[%q] = true', propset, prop)) @@ -1122,6 +1135,7 @@ local function generate_main_validator_ctx(schema, options) -- * the custom callbacks (used to customize various aspects of validation -- or for dependency injection) ctx:preface('local uservalues, lib, custom = ...') + ctx:preface('local locals = {}') ctx:stmt('return ', ctx:validator(nil, schema)) return ctx end diff --git a/t/200more_variables.lua b/t/200more_variables.lua new file mode 100644 index 0000000..d625e91 --- /dev/null +++ b/t/200more_variables.lua @@ -0,0 +1,19 @@ +local jsonschema = require 'jsonschema' + +----------------------------------------------------- test case 1 +local rule = { + type = "object", + properties = {} +} + +for i = 1, 256 do + rule.properties["key" .. i] = { + type = "string" + } +end + +local status, err = pcall(jsonschema.generate_validator, rule) +if not status then + ngx.say("fail: check 200 more variables: ", err) +end +ngx.say("passed: check 200 more variables")