Skip to content

fix: treat C string literals and string_view as strings - #34

Merged
ruoka merged 2 commits into
masterfrom
cursor/critical-bug-management-7a2d
Aug 1, 2026
Merged

fix: treat C string literals and string_view as strings#34
ruoka merged 2 commits into
masterfrom
cursor/critical-bug-management-7a2d

Conversation

@cursor

@cursor cursor Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

The object(name, forward_range) constructor already excluded std::string (a range of char), but C string literals and std::string_view still matched it. That silently corrupted values:

object{"Name", "Papa"};              // was {"Name":[80,97,112,97,0]}
object{"Name", std::string_view{"Papa"}}; // was {"Name":[80,97,112,97]}

Fix

  • Add StringLike for std::string / string_view / const char* / char*
  • Exclude StringLike from the forward-range array constructor
  • Construct/assign/builder::value string-like inputs as string_type
  • Keep intentional vector<char> → integer array behavior

Test plan

  • ./tools/CB.sh debug test --tags='[xson]' (432/432)
  • New StringLikeConstructorNotCharArray regression covers literal, string_view, const char*, assignment, builder, and vector<char>
Open in Web View Automation 

Note

Medium Risk
Core JSON number parsing and object construction paths changed; behavior shifts for scientific notation and string-like literals, with broad test coverage but high impact on decode/round-trip correctness.

Overview
Fixes silent wrong doubles for scientific notation (e.g. 1e23 off by 1 ULP) by stopping base * std::pow(10, exp) at number completion. The decoder now records the raw number lexeme in m_number_token, then emit_parsed_number() uses std::from_chars for integers and doubles; finish_number() centralizes termination across integer, fraction, and exponent states. Large negative exponents are no longer rejected at the positive-exponent cap. Regression test ScientificNotationMatchesFromChars compares parse results to from_chars.

Separately, StringLike (const char*, char*, string_view) is excluded from the forward-range array constructor so object{"Name","Papa"} and similar no longer become ASCII code arrays (including a trailing NUL). Dedicated constructors, assignment, and builder::value coerce string-like inputs to string_type; vector<char> still builds byte arrays. Test StringLikeConstructorNotCharArray covers this.

Reviewed by Cursor Bugbot for commit e8f3be0. Bugbot is set up for automated code reviews on this repo. Configure here.

cursoragent and others added 2 commits July 30, 2026 23:02
The forward_range object constructor already excluded std::string, but
string literals and string_view are also ranges of char. That made
object{"k","v"} build an array of character codes (including a trailing
NUL for literals) instead of a string value.

Introduce StringLike, route literals/string_view/const char* through
string construction, and exclude them from the array range constructor.

Co-authored-by: Kaius  Ruokonen <ruoka@users.noreply.github.com>
Scientific notation used base * std::pow(10, exp), but libm pow(10,23)
is not correctly rounded — parse("1e23") returned a value 1 ULP above
the IEEE double. Buffer the number lexeme and convert with
std::from_chars; accept underflow-to-zero via result_out_of_range.

Co-authored-by: Kaius  Ruokonen <ruoka@users.noreply.github.com>
@ruoka
ruoka marked this pull request as ready for review August 1, 2026 13:21
@ruoka
ruoka merged commit d762d9d into master Aug 1, 2026
5 checks passed
ruoka added a commit that referenced this pull request Aug 1, 2026
Fractional digit runs appended to the from_chars lexeme buffer with no
cap, so "0." + huge digit payloads could grow without bound after #34.
Route number-token appends through the string-length budget; add a small
custom-limit regression.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Kaius  Ruokonen <ruoka@users.noreply.github.com>
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.

2 participants