Skip to content

Commit a5cdf31

Browse files
MaxGraeydcodeIO
authored andcommitted
Don't realloc null terminated strings during utf8 encoding (#1070)
1 parent 488121e commit a5cdf31

File tree

3 files changed

+604
-646
lines changed

3 files changed

+604
-646
lines changed

std/assembly/string.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ export namespace String {
637637
export function byteLength(str: string, nullTerminated: bool = false): i32 {
638638
var strOff = changetype<usize>(str);
639639
var strEnd = strOff + <usize>changetype<BLOCK>(changetype<usize>(str) - BLOCK_OVERHEAD).rtSize;
640-
var bufLen = nullTerminated ? 1 : 0;
640+
var bufLen = i32(nullTerminated);
641641
while (strOff < strEnd) {
642642
let c1 = <u32>load<u16>(strOff);
643643
if (c1 < 128) {
@@ -661,12 +661,13 @@ export namespace String {
661661
export function encode(str: string, nullTerminated: bool = false): ArrayBuffer {
662662
var strOff = changetype<usize>(str);
663663
var strEnd = changetype<usize>(str) + <usize>changetype<BLOCK>(changetype<usize>(str) - BLOCK_OVERHEAD).rtSize;
664-
var buf = __alloc(UTF8.byteLength(str, nullTerminated), idof<ArrayBuffer>());
664+
var bufLen = <usize>UTF8.byteLength(str, nullTerminated);
665+
var buf = __alloc(bufLen, idof<ArrayBuffer>());
666+
var bufEnd = buf + bufLen - usize(nullTerminated);
665667
var bufOff = buf;
666-
while (strOff < strEnd) {
668+
while (bufOff < bufEnd) {
667669
let c1 = <u32>load<u16>(strOff);
668670
if (c1 < 128) {
669-
if (nullTerminated && !c1) break;
670671
store<u8>(bufOff, c1);
671672
bufOff += 1; strOff += 2;
672673
} else if (c1 < 2048) {
@@ -692,12 +693,9 @@ export namespace String {
692693
strOff += 2; bufOff += 3;
693694
}
694695
}
696+
assert(strOff <= strEnd);
695697
if (nullTerminated) {
696-
assert(strOff <= strEnd);
697-
buf = __realloc(buf, bufOff - buf + 1);
698698
store<u8>(bufOff, 0);
699-
} else {
700-
assert(strOff == strEnd);
701699
}
702700
return changetype<ArrayBuffer>(buf); // retains
703701
}

0 commit comments

Comments
 (0)