feat: String_ToFloat + Json escape sequence support

- Add bux_str_to_float() C runtime wrapper (strtod)
- Add String_ToFloat() in library/std/String.bux
- Update JsonParser_ParseNumber to use String_ToFloat (decimals now work)
- Update JsonParser_ParseString to decode escape sequences (\n, \t, \r, \", \\, \b, \f)
- Fix use-after-free in JsonParser_ParseString: String_Copy before StringBuilder_Free
This commit is contained in:
2026-06-05 22:35:50 +03:00
parent d0de9c2abf
commit 154579b30d
4 changed files with 36 additions and 6 deletions
+24 -6
View File
@@ -236,7 +236,7 @@ func JsonParser_ParseString(p: *JsonParser) -> String {
return "";
}
JsonParser_Advance(p);
let start: uint = p.pos;
let sb: StringBuilder = StringBuilder_New();
while true {
let c: int = JsonParser_Peek(p);
if c == 0 || c == 34 {
@@ -244,22 +244,40 @@ func JsonParser_ParseString(p: *JsonParser) -> String {
}
if c == 92 {
JsonParser_Advance(p);
if JsonParser_Peek(p) == 0 {
let esc: int = JsonParser_Peek(p);
if esc == 0 {
p.error = "Unterminated string escape";
StringBuilder_Free(&sb);
return "";
}
if esc == 110 { StringBuilder_AppendChar(&sb, 10 as char8); } // \n
else if esc == 116 { StringBuilder_AppendChar(&sb, 9 as char8); } // \t
else if esc == 114 { StringBuilder_AppendChar(&sb, 13 as char8); } // \r
else if esc == 98 { StringBuilder_AppendChar(&sb, 8 as char8); } // \b
else if esc == 102 { StringBuilder_AppendChar(&sb, 12 as char8); } // \f
else if esc == 34 { StringBuilder_AppendChar(&sb, 34 as char8); } // \"
else if esc == 92 { StringBuilder_AppendChar(&sb, 92 as char8); } // \\
else {
// Unknown escape — keep literal
StringBuilder_AppendChar(&sb, 92 as char8);
StringBuilder_AppendChar(&sb, esc as char8);
}
JsonParser_Advance(p);
} else {
StringBuilder_AppendChar(&sb, c as char8);
JsonParser_Advance(p);
}
}
let endPos: uint = p.pos;
if JsonParser_Peek(p) != 34 {
p.error = "Unterminated string";
StringBuilder_Free(&sb);
return "";
}
JsonParser_Advance(p);
return String_Slice(p.src, start, endPos - start);
let raw: String = StringBuilder_Build(&sb);
let result: String = String_Copy(raw);
StringBuilder_Free(&sb);
return result;
}
func JsonParser_ParseNumber(p: *JsonParser) -> JsonValue {
@@ -288,8 +306,8 @@ func JsonParser_ParseNumber(p: *JsonParser) -> JsonValue {
}
}
let numStr: String = String_Slice(p.src, start, p.pos - start);
let n: int64 = String_ToInt(numStr);
return Json_Number(n as float64);
let n: float64 = String_ToFloat(numStr);
return Json_Number(n);
}
func JsonParser_ParseArray(p: *JsonParser) -> JsonValue {
+6
View File
@@ -179,6 +179,12 @@ func String_Replace(s: String, old: String, new: String) -> String {
return result;
}
extern func bux_str_to_float(s: String) -> float64;
func String_ToFloat(s: String) -> float64 {
return bux_str_to_float(s);
}
func String_FromFloat(f: float64) -> String {
return bux_float_to_string(f);
}