From b8bf36060c0f63d5ef7839d9fcf37e90b57afb02 Mon Sep 17 00:00:00 2001 From: Mike Siomkin Date: Sat, 28 Dec 2019 17:00:25 +0300 Subject: [PATCH] Implement screening of quotes in constants Use backslash symbol (\) to screen single and double quotes and backslashes inside string constants used as function arguments. --- luaxp.lua | 13 +++++++++++-- test/test.lua | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/luaxp.lua b/luaxp.lua index d1663d7..43a4314 100644 --- a/luaxp.lua +++ b/luaxp.lua @@ -57,7 +57,8 @@ local TNUL = 'null' local NULLATOM = { __type=TNUL } setmetatable( NULLATOM, { __tostring=function() return "null" end } ) -local charmap = { t = "\t", r = "\r", n = "\n" } +local charmap = { t = "\t", r = "\r", n = "\n", + ["\\"] = "\\", ["'"] = "'", ['"'] = '"' } local reservedWords = { ['false']=false, ['true']=true @@ -440,6 +441,14 @@ local function xp_mktime( yy, mm, dd, hours, mins, secs ) return os.time(pt) end +local function xp_enquote(s, q) + if base.type(s) ~= "string" then evalerror("String required") end + if q ~= "'" and q ~= '"' then evalerror("Illegal quotation mark") end + s = s:gsub("\\", "\\\\") + s = s:gsub(q, "\\" .. q) + return q .. s .. q +end + local function xp_rtrim(s) if base.type(s) ~= "string" then evalerror("String required") end return s:gsub("%s+$", "") @@ -747,7 +756,7 @@ local function scan_fref( expr, index, name ) -- Start of string? local qq = ch index, ch = scan_string( expr, index ) - subexp = subexp .. qq .. ch.value .. qq + subexp = subexp .. xp_enquote(ch.value, qq) elseif ch == ',' and parenLevel == 1 then -- completed subexpression subexp = xp_trim( subexp ) D("scan_fref: handling argument=%1", subexp) diff --git a/test/test.lua b/test/test.lua index c65d3c2..e3b6e43 100644 --- a/test/test.lua +++ b/test/test.lua @@ -374,6 +374,9 @@ local function doStringFuncTests() eval("sub('The rain in Spain stays mainly in the plain.', 35, -5)", "the pl") eval("sub('The rain in Spain stays mainly in the plain.', 39)", "plain.") eval("sub('[in brackets]', 2, -2)", "in brackets") + eval("sub('Jack\\'s house', 1, 6)", "Jack's") + eval("sub('A back slash (\\\\) is a screening character', 14, 16)", "(\\)") + eval('sub("Start from a \\"Hello, World!\\" program", 14, 28)', '"Hello, world!"') eval("find('The rain in Spain stays mainly in the plain.', 'not there')", 0) eval("find('The rain in Spain stays mainly in the plain.', 'plain.')", 39) eval("upper('The rain in Spain stays mainly in the plain.')", "THE RAIN IN SPAIN STAYS MAINLY IN THE PLAIN.")