aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-09-03 13:14:56 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-09-03 13:14:56 -0300
commit9db4bfed6bb9d5828c99c0f24749eedf54d70cc2 (patch)
tree5a7bae2573f3e08813680a2506840f2356d18cd8 /testes
parent91673a8ec0ae55e188a790bd2dfdc99246adf20e (diff)
downloadlua-9db4bfed6bb9d5828c99c0f24749eedf54d70cc2.tar.gz
lua-9db4bfed6bb9d5828c99c0f24749eedf54d70cc2.tar.bz2
lua-9db4bfed6bb9d5828c99c0f24749eedf54d70cc2.zip
Revamp of format validation in 'string.format'
When calling 'sprintf', not all conversion specifiers accept all flags; some combinations are undefined behavior.
Diffstat (limited to 'testes')
-rw-r--r--testes/strings.lua36
1 files changed, 28 insertions, 8 deletions
diff --git a/testes/strings.lua b/testes/strings.lua
index 61a06a25..184fa651 100644
--- a/testes/strings.lua
+++ b/testes/strings.lua
@@ -202,13 +202,11 @@ assert(string.format("\0%c\0%c%x\0", string.byte("\xe4"), string.byte("b"), 140)
202 "\0\xe4\0b8c\0") 202 "\0\xe4\0b8c\0")
203assert(string.format('') == "") 203assert(string.format('') == "")
204assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) == 204assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) ==
205 string.format("%c%c%c%c", 34, 48, 90, 100)) 205 string.format("%1c%-c%-1c%c", 34, 48, 90, 100))
206assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be') 206assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be')
207assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023") 207assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023")
208assert(tonumber(string.format("%f", 10.3)) == 10.3) 208assert(tonumber(string.format("%f", 10.3)) == 10.3)
209x = string.format('"%-50s"', 'a') 209assert(string.format('"%-50s"', 'a') == '"a' .. string.rep(' ', 49) .. '"')
210assert(#x == 52)
211assert(string.sub(x, 1, 4) == '"a ')
212 210
213assert(string.format("-%.20s.20s", string.rep("%", 2000)) == 211assert(string.format("-%.20s.20s", string.rep("%", 2000)) ==
214 "-"..string.rep("%", 20)..".20s") 212 "-"..string.rep("%", 20)..".20s")
@@ -237,7 +235,6 @@ end
237 235
238assert(string.format("\0%s\0", "\0\0\1") == "\0\0\0\1\0") 236assert(string.format("\0%s\0", "\0\0\1") == "\0\0\0\1\0")
239checkerror("contains zeros", string.format, "%10s", "\0") 237checkerror("contains zeros", string.format, "%10s", "\0")
240checkerror("cannot have modifiers", string.format, "%10q", "1")
241 238
242-- format x tostring 239-- format x tostring
243assert(string.format("%s %s", nil, true) == "nil true") 240assert(string.format("%s %s", nil, true) == "nil true")
@@ -341,6 +338,21 @@ do print("testing 'format %a %A'")
341end 338end
342 339
343 340
341-- testing some flags (all these results are required by ISO C)
342assert(string.format("%#12o", 10) == " 012")
343assert(string.format("%#10x", 100) == " 0x64")
344assert(string.format("%#-17X", 100) == "0X64 ")
345assert(string.format("%013i", -100) == "-000000000100")
346assert(string.format("%2.5d", -100) == "-00100")
347assert(string.format("%.u", 0) == "")
348assert(string.format("%+#014.0f", 100) == "+000000000100.")
349assert(string.format("% 1.0E", 100) == " 1E+02")
350assert(string.format("%-16c", 97) == "a ")
351assert(string.format("%+.3G", 1.5) == "+1.5")
352assert(string.format("% .1g", 2^10) == " 1e+03")
353assert(string.format("%.0s", "alo") == "")
354assert(string.format("%.s", "alo") == "")
355
344-- errors in format 356-- errors in format
345 357
346local function check (fmt, msg) 358local function check (fmt, msg)
@@ -348,13 +360,21 @@ local function check (fmt, msg)
348end 360end
349 361
350local aux = string.rep('0', 600) 362local aux = string.rep('0', 600)
351check("%100.3d", "too long") 363check("%100.3d", "invalid conversion")
352check("%1"..aux..".3d", "too long") 364check("%1"..aux..".3d", "too long")
353check("%1.100d", "too long") 365check("%1.100d", "invalid conversion")
354check("%10.1"..aux.."004d", "too long") 366check("%10.1"..aux.."004d", "too long")
355check("%t", "invalid conversion") 367check("%t", "invalid conversion")
356check("%"..aux.."d", "repeated flags") 368check("%"..aux.."d", "too long")
357check("%d %d", "no value") 369check("%d %d", "no value")
370check("%010c", "invalid conversion")
371check("%.10c", "invalid conversion")
372check("%0.34s", "invalid conversion")
373check("%#i", "invalid conversion")
374check("%3.1p", "invalid conversion")
375check("%0.s", "invalid conversion")
376check("%10q", "cannot have modifiers")
377check("%F", "invalid conversion") -- useless and not in C89
358 378
359 379
360assert(load("return 1\n--comment without ending EOL")() == 1) 380assert(load("return 1\n--comment without ending EOL")() == 1)