-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(plugin): cleanup and fix error handling (#12912)
* chore(ai-prompt-template): cleanup code improve error handling * review comments
- Loading branch information
Showing
4 changed files
with
210 additions
and
219 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,66 @@ | ||
local _S = {} | ||
|
||
-- imports | ||
local fmt = string.format | ||
-- | ||
|
||
-- globals | ||
local GSUB_REPLACE_PATTERN = "{{([%w_]+)}}" | ||
-- | ||
|
||
local function backslash_replacement_function(c) | ||
if c == "\n" then | ||
return "\\n" | ||
elseif c == "\r" then | ||
return "\\r" | ||
elseif c == "\t" then | ||
return "\\t" | ||
elseif c == "\b" then | ||
return "\\b" | ||
elseif c == "\f" then | ||
return "\\f" | ||
elseif c == '"' then | ||
return '\\"' | ||
elseif c == '\\' then | ||
return '\\\\' | ||
else | ||
return string.format("\\u%04x", c:byte()) | ||
end | ||
end | ||
local cjson = require "cjson.safe" | ||
|
||
local chars_to_be_escaped_in_JSON_string | ||
= '[' | ||
.. '"' -- class sub-pattern to match a double quote | ||
.. '%\\' -- class sub-pattern to match a backslash | ||
.. '%z' -- class sub-pattern to match a null | ||
.. '\001' .. '-' .. '\031' -- class sub-pattern to match control characters | ||
.. ']' | ||
|
||
-- borrowed from turbo-json | ||
local function sanitize_parameter(s) | ||
if type(s) ~= "string" or s == "" then | ||
return nil, nil, "only string arguments are supported" | ||
end | ||
local _M = {} | ||
|
||
-- check if someone is trying to inject JSON control characters to close the command | ||
if s:sub(-1) == "," then | ||
s = s:sub(1, -1) | ||
end | ||
|
||
return s:gsub(chars_to_be_escaped_in_JSON_string, backslash_replacement_function), nil | ||
end | ||
|
||
function _S:new(o) | ||
local o = o or {} | ||
setmetatable(o, self) | ||
self.__index = self | ||
--- Sanitize properties object. | ||
-- Incoming user-provided JSON object may contain any kind of data. | ||
-- @tparam table params the kv table to sanitize | ||
-- @treturn[1] table the escaped values (without quotes) | ||
-- @treturn[2] nil | ||
-- @treturn[2] string error message | ||
local function sanitize_properties(params) | ||
local result = {} | ||
|
||
return o | ||
if type(params) ~= "table" then | ||
return nil, "properties must be an object" | ||
end | ||
|
||
for k,v in pairs(params) do | ||
if type(k) ~= "string" then | ||
return nil, "properties must be an object" | ||
end | ||
if type(v) == "string" then | ||
result[k] = cjson.encode(v):sub(2, -2) -- remove quotes | ||
else | ||
return nil, "property values must be a string, got " .. type(v) | ||
end | ||
end | ||
|
||
return result | ||
end | ||
|
||
|
||
function _S:render(template, properties) | ||
local sanitized_properties = {} | ||
local err, _ | ||
|
||
for k, v in pairs(properties) do | ||
sanitized_properties[k], _, err = sanitize_parameter(v) | ||
if err then return nil, err end | ||
end | ||
do | ||
local GSUB_REPLACE_PATTERN = "{{([%w_]+)}}" | ||
|
||
local result = template.template:gsub(GSUB_REPLACE_PATTERN, sanitized_properties) | ||
function _M.render(template, properties) | ||
local sanitized_properties, err = sanitize_properties(properties) | ||
if not sanitized_properties then | ||
return nil, err | ||
end | ||
|
||
-- find any missing variables | ||
local errors = {} | ||
local error_string | ||
for w in (result):gmatch(GSUB_REPLACE_PATTERN) do | ||
errors[w] = true | ||
end | ||
local result = template.template:gsub(GSUB_REPLACE_PATTERN, sanitized_properties) | ||
|
||
if next(errors) ~= nil then | ||
for k, _ in pairs(errors) do | ||
if not error_string then | ||
error_string = fmt("missing template parameters: [%s]", k) | ||
else | ||
error_string = fmt("%s, [%s]", error_string, k) | ||
-- find any missing variables | ||
local errors = {} | ||
local seen_before = {} | ||
for w in result:gmatch(GSUB_REPLACE_PATTERN) do | ||
if not seen_before[w] then | ||
seen_before[w] = true | ||
errors[#errors+1] = "[" .. w .. "]" | ||
end | ||
end | ||
end | ||
|
||
return result, error_string | ||
if errors[1] then | ||
return nil, "missing template parameters: " .. table.concat(errors, ", ") | ||
end | ||
|
||
return result | ||
end | ||
end | ||
|
||
return _S | ||
|
||
return _M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
0b1705e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bazel Build
Docker image available
kong/kong:0b1705ec0a4480596f6a1d2923a809d1f458a07b
Artifacts available https://github.com/Kong/kong/actions/runs/9000432206