ropes: make lib & compiler frmt more similar, fix out-of-bounds accesses in lib ropes

This commit is contained in:
Jacek Sieka 2015-03-29 22:25:11 +08:00
commit aafbe5c866
2 changed files with 30 additions and 15 deletions

View file

@ -264,8 +264,22 @@ proc `%`*(frmt: TFormatStr, args: openArray[PRope]): PRope =
while true: while true:
j = j * 10 + ord(frmt[i]) - ord('0') j = j * 10 + ord(frmt[i]) - ord('0')
inc(i) inc(i)
if (i > length - 1) or frmt[i] notin {'0'..'9'}: break if (i >= length) or frmt[i] notin {'0'..'9'}: break
num = j num = j
if j > high(args) + 1:
errorHandler(rInvalidFormatStr, $(j))
else:
add(result, args[j-1])
of '{':
inc(i)
var j = 0
while i < length and frmt[i] in {'0'..'9'}:
j = j * 10 + ord(frmt[i]) - ord('0')
inc(i)
num = j
if i < length and frmt[i] == '}': inc(i)
else: errorHandler(rInvalidFormatStr, $(frmt[i]))
if j > high(args) + 1: if j > high(args) + 1:
errorHandler(rInvalidFormatStr, $(j)) errorHandler(rInvalidFormatStr, $(j))
else: else:

View file

@ -290,8 +290,8 @@ when false:
else: break else: break
if i - 1 >= start: if i - 1 >= start:
add(result, substr(frmt, start, i-1)) add(result, substr(frmt, start, i-1))
proc `%`*(frmt: string, args: openArray[Rope]): Rope {. proc `%`*(frmt: string, args: openArray[Rope]): Rope {.
rtl, extern: "nroFormat".} = rtl, extern: "nroFormat".} =
## `%` substitution operator for ropes. Does not support the ``$identifier`` ## `%` substitution operator for ropes. Does not support the ``$identifier``
## nor ``${identifier}`` notations. ## nor ``${identifier}`` notations.
@ -299,39 +299,40 @@ proc `%`*(frmt: string, args: openArray[Rope]): Rope {.
var length = len(frmt) var length = len(frmt)
result = nil result = nil
var num = 0 var num = 0
while i < length: while i < length:
if frmt[i] == '$': if frmt[i] == '$':
inc(i) inc(i)
case frmt[i] case frmt[i]
of '$': of '$':
add(result, "$") add(result, "$")
inc(i) inc(i)
of '#': of '#':
inc(i) inc(i)
add(result, args[num]) add(result, args[num])
inc(num) inc(num)
of '0'..'9': of '0'..'9':
var j = 0 var j = 0
while true: while true:
j = j * 10 + ord(frmt[i]) - ord('0') j = j * 10 + ord(frmt[i]) - ord('0')
inc(i) inc(i)
if frmt[i] notin {'0'..'9'}: break if (i >= length) or frmt[i] notin {'0'..'9'}: break
add(result, args[j-1]) add(result, args[j-1])
of '{': of '{':
inc(i) inc(i)
var j = 0 var j = 0
while frmt[i] in {'0'..'9'}: while i < length and frmt[i] in {'0'..'9'}:
j = j * 10 + ord(frmt[i]) - ord('0') j = j * 10 + ord(frmt[i]) - ord('0')
inc(i) inc(i)
if frmt[i] == '}': inc(i) if i < length and frmt[i] == '}': inc(i)
else: raise newException(ValueError, "invalid format string") else: raise newException(ValueError, "invalid format string")
add(result, args[j-1]) add(result, args[j-1])
else: raise newException(ValueError, "invalid format string") else: raise newException(ValueError, "invalid format string")
var start = i var start = i
while i < length: while i < length:
if frmt[i] != '$': inc(i) if frmt[i] != '$': inc(i)
else: break else: break
if i - 1 >= start: if i - 1 >= start:
add(result, substr(frmt, start, i - 1)) add(result, substr(frmt, start, i - 1))
proc addf*(c: var Rope, frmt: string, args: openArray[Rope]) {. proc addf*(c: var Rope, frmt: string, args: openArray[Rope]) {.