diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-09-03 13:14:56 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-09-03 13:14:56 -0300 |
commit | 9db4bfed6bb9d5828c99c0f24749eedf54d70cc2 (patch) | |
tree | 5a7bae2573f3e08813680a2506840f2356d18cd8 /testes | |
parent | 91673a8ec0ae55e188a790bd2dfdc99246adf20e (diff) | |
download | lua-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.lua | 36 |
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") |
203 | assert(string.format('') == "") | 203 | assert(string.format('') == "") |
204 | assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) == | 204 | assert(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)) |
206 | assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be') | 206 | assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be') |
207 | assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023") | 207 | assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023") |
208 | assert(tonumber(string.format("%f", 10.3)) == 10.3) | 208 | assert(tonumber(string.format("%f", 10.3)) == 10.3) |
209 | x = string.format('"%-50s"', 'a') | 209 | assert(string.format('"%-50s"', 'a') == '"a' .. string.rep(' ', 49) .. '"') |
210 | assert(#x == 52) | ||
211 | assert(string.sub(x, 1, 4) == '"a ') | ||
212 | 210 | ||
213 | assert(string.format("-%.20s.20s", string.rep("%", 2000)) == | 211 | assert(string.format("-%.20s.20s", string.rep("%", 2000)) == |
214 | "-"..string.rep("%", 20)..".20s") | 212 | "-"..string.rep("%", 20)..".20s") |
@@ -237,7 +235,6 @@ end | |||
237 | 235 | ||
238 | assert(string.format("\0%s\0", "\0\0\1") == "\0\0\0\1\0") | 236 | assert(string.format("\0%s\0", "\0\0\1") == "\0\0\0\1\0") |
239 | checkerror("contains zeros", string.format, "%10s", "\0") | 237 | checkerror("contains zeros", string.format, "%10s", "\0") |
240 | checkerror("cannot have modifiers", string.format, "%10q", "1") | ||
241 | 238 | ||
242 | -- format x tostring | 239 | -- format x tostring |
243 | assert(string.format("%s %s", nil, true) == "nil true") | 240 | assert(string.format("%s %s", nil, true) == "nil true") |
@@ -341,6 +338,21 @@ do print("testing 'format %a %A'") | |||
341 | end | 338 | end |
342 | 339 | ||
343 | 340 | ||
341 | -- testing some flags (all these results are required by ISO C) | ||
342 | assert(string.format("%#12o", 10) == " 012") | ||
343 | assert(string.format("%#10x", 100) == " 0x64") | ||
344 | assert(string.format("%#-17X", 100) == "0X64 ") | ||
345 | assert(string.format("%013i", -100) == "-000000000100") | ||
346 | assert(string.format("%2.5d", -100) == "-00100") | ||
347 | assert(string.format("%.u", 0) == "") | ||
348 | assert(string.format("%+#014.0f", 100) == "+000000000100.") | ||
349 | assert(string.format("% 1.0E", 100) == " 1E+02") | ||
350 | assert(string.format("%-16c", 97) == "a ") | ||
351 | assert(string.format("%+.3G", 1.5) == "+1.5") | ||
352 | assert(string.format("% .1g", 2^10) == " 1e+03") | ||
353 | assert(string.format("%.0s", "alo") == "") | ||
354 | assert(string.format("%.s", "alo") == "") | ||
355 | |||
344 | -- errors in format | 356 | -- errors in format |
345 | 357 | ||
346 | local function check (fmt, msg) | 358 | local function check (fmt, msg) |
@@ -348,13 +360,21 @@ local function check (fmt, msg) | |||
348 | end | 360 | end |
349 | 361 | ||
350 | local aux = string.rep('0', 600) | 362 | local aux = string.rep('0', 600) |
351 | check("%100.3d", "too long") | 363 | check("%100.3d", "invalid conversion") |
352 | check("%1"..aux..".3d", "too long") | 364 | check("%1"..aux..".3d", "too long") |
353 | check("%1.100d", "too long") | 365 | check("%1.100d", "invalid conversion") |
354 | check("%10.1"..aux.."004d", "too long") | 366 | check("%10.1"..aux.."004d", "too long") |
355 | check("%t", "invalid conversion") | 367 | check("%t", "invalid conversion") |
356 | check("%"..aux.."d", "repeated flags") | 368 | check("%"..aux.."d", "too long") |
357 | check("%d %d", "no value") | 369 | check("%d %d", "no value") |
370 | check("%010c", "invalid conversion") | ||
371 | check("%.10c", "invalid conversion") | ||
372 | check("%0.34s", "invalid conversion") | ||
373 | check("%#i", "invalid conversion") | ||
374 | check("%3.1p", "invalid conversion") | ||
375 | check("%0.s", "invalid conversion") | ||
376 | check("%10q", "cannot have modifiers") | ||
377 | check("%F", "invalid conversion") -- useless and not in C89 | ||
358 | 378 | ||
359 | 379 | ||
360 | assert(load("return 1\n--comment without ending EOL")() == 1) | 380 | assert(load("return 1\n--comment without ending EOL")() == 1) |