Fix bounds checking

Fixes #1410
This commit is contained in:
Zed
2026-06-11 23:26:21 +02:00
parent 7eed720894
commit bd9d492d36
2 changed files with 35 additions and 14 deletions
+13 -5
View File
@@ -140,25 +140,30 @@ proc pageDesc*(user: User): string =
"The latest tweets from " & user.fullname
proc getJoinDate*(user: User): string =
if user.joinDate.year == 0: return ""
user.joinDate.format("'Joined' MMMM YYYY")
proc getJoinDateFull*(user: User): string =
if user.joinDate.year == 0: return ""
user.joinDate.format("h:mm tt - d MMM YYYY")
proc getTime*(tweet: Tweet): string =
if tweet.time.year == 0: return ""
tweet.time.format("MMM d', 'YYYY' · 'h:mm tt' UTC'")
proc getRfc822Time*(tweet: Tweet): string =
if tweet.time.year == 0: return ""
tweet.time.format("ddd', 'dd MMM yyyy HH:mm:ss 'GMT'")
proc getShortTime*(tweet: Tweet): string =
proc getShortTime*(time: DateTime): string =
if time.year == 0: return ""
let now = now()
let since = now - tweet.time
let since = now - time
if now.year != tweet.time.year:
result = tweet.time.format("d MMM yyyy")
if now.year != time.year:
result = time.format("d MMM yyyy")
elif since.inDays >= 1:
result = tweet.time.format("MMM d")
result = time.format("MMM d")
elif since.inHours >= 1:
result = $since.inHours & "h"
elif since.inMinutes >= 1:
@@ -168,6 +173,9 @@ proc getShortTime*(tweet: Tweet): string =
else:
result = "now"
proc getShortTime*(tweet: Tweet): string =
getShortTime(tweet.time)
proc getDuration*(ms: int): string =
let
sec = int(round(ms / 1000))
+22 -9
View File
@@ -202,19 +202,32 @@ proc extractHashtags(result: var seq[ReplaceSlice]; js: JsonNode) =
proc replacedWith(runes: seq[Rune]; repls: openArray[ReplaceSlice];
textSlice: Slice[int]): string =
let
runeLen = runes.len
safeStart = max(0, textSlice.a)
safeEnd = min(runeLen, textSlice.b)
var validRepls: seq[ReplaceSlice]
for rep in repls:
if rep.slice.a >= 0 and rep.slice.b >= 0 and rep.slice.b < runeLen and rep.slice.a <= rep.slice.b:
validRepls.add rep
template extractLowerBound(i: int; idx): int =
if i > 0: repls[idx].slice.b.succ else: textSlice.a
if i > 0: min(validRepls[idx].slice.b.succ, runeLen) else: safeStart
result = newStringOfCap(runes.len)
for i, rep in repls:
result.add $runes[extractLowerBound(i, i - 1) ..< rep.slice.a]
for i, rep in validRepls:
let lower = extractLowerBound(i, i - 1)
if lower < rep.slice.a:
result.add $runes[lower ..< rep.slice.a]
case rep.kind
of rkHashtag:
let
name = $runes[rep.slice.a.succ .. rep.slice.b]
symbol = $runes[rep.slice.a]
result.add a(symbol & name, href = "/search?f=tweets&q=%23" & name)
if rep.slice.a.succ <= rep.slice.b:
let
name = $runes[rep.slice.a.succ .. rep.slice.b]
symbol = $runes[rep.slice.a]
result.add a(symbol & name, href = "/search?f=tweets&q=%23" & name)
of rkMention:
result.add a($runes[rep.slice], href = rep.url, title = rep.display)
of rkUrl:
@@ -222,8 +235,8 @@ proc replacedWith(runes: seq[Rune]; repls: openArray[ReplaceSlice];
of rkRemove:
discard
let rest = extractLowerBound(repls.len, ^1) ..< textSlice.b
if rest.a <= rest.b:
let rest = extractLowerBound(validRepls.len, ^1) ..< safeEnd
if rest.a >= 0 and rest.a <= rest.b and rest.b <= runeLen:
result.add $runes[rest]
proc deduplicate(s: var seq[ReplaceSlice]) =