Skip to content

String concatenation copies with the lengths it measured, not strcpy/strcat - #520

Merged
ASDAlexander77 merged 1 commit into
mainfrom
string-concat-memcpy
Oct 5, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
string-concat-memcpy

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Summary

  • ts.StringConcat measured each operand with strlen to size the result, then copied with strcpy/strcat. Those copies were unbounded, and strcat rescans the result for every operand. Each operand is now copied with llvm.memcpy at its offset, bounded by the length that sized the buffer, and the result gets one terminator. No C string function is left in the lowering.
  • _itoa / _i64toa / _gcvt in ConvertLogic.h are removed, along with the USE_SPRINTF switch. USE_SPRINTF was always defined, so number-to-string already went through the bounded sprintf_s/snprintf path (ts.ConvertF) on every target.

These are the compiler half of a bounds-correctness pass. The DefaultLib half is ASDAlexander77/TypeScriptCompilerDefaultLib (branch string-bounds-checks, fixes ASDAlexander77/TypeScriptCompilerDefaultLib#27). The two are independent.

Test plan

  • New 00string_concat_bounds.ts (compile + jit, and in TSLANG_CORPUS for rc/none): empty, null, many and number operands, a result built in a loop
  • --emit=llvm has no strcpy/strcat calls
  • Windows Release ctest -C Release: 3898/3898
  • CI (Linux, debug)

🤖 Generated with Claude Code

…strcat

ts.StringConcat measured every operand with strlen to size the result, then
copied with strcpy and strcat: unbounded copies, and strcat rescans the result
for every operand. Each operand is now copied with llvm.memcpy at its offset,
bounded by the length that sized the buffer, and the result gets one
terminator at the end. No C string function is left in the lowering.

The _itoa, _i64toa and _gcvt conversions are removed: USE_SPRINTF was always
defined, so number-to-string has gone through the bounded sprintf_s/snprintf
path (ts.ConvertF) on every target, and the MSVC-only helpers were dead code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 8161fdd into main Oct 5, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the string-concat-memcpy branch October 5, 2026 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

String.slice(start, end) with end < start overflows the result buffer

1 participant