From abdf1ca559e08539f2b5124e049f3a2497c39f61 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 6 Jul 2026 18:53:04 +0200 Subject: [PATCH] SSO: bugfix (#25967) --- lib/system/strs_v3.nim | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/system/strs_v3.nim b/lib/system/strs_v3.nim index 65c0fa88c9..a42e9a0e05 100644 --- a/lib/system/strs_v3.nim +++ b/lib/system/strs_v3.nim @@ -514,10 +514,25 @@ proc setLengthStr(s: var SmallString; newLen: int; zeroing: bool) = s.more.fullLen = newLen s.more.data[newLen] = '\0' else: - # shared or static block: detach and go back to inline + # shared or static block: detach from the shared/static buffer. if newLen <= 0: nimDestroyStrV1(s) s.bytes = 0 + elif newLen > PayloadSize: + # Still too long for inline: detach into a fresh unique heap block + # rather than overflowing the inline overlay. + let old = s.more + let p = cast[ptr LongString](alloc(LongStringDataOffset + newLen + 1)) + p.rc = 1 + p.fullLen = newLen + p.capImpl = newLen + copyMem(addr p.data[0], addr old.data[0], newLen) + p.data[newLen] = '\0' + if slen == HeapSlen and atomicSubFetch(old.rc, 1) == 0: + dealloc(old) + s.more = p + setSSLen(s, HeapSlen) + copyMem(inlinePtr(s), addr p.data[0], AlwaysAvail) # sync hot prefix else: let old = s.more let inl = inlinePtr(s)