fix: treat C string literals and string_view as strings - #34
Merged
Conversation
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
marked this pull request as ready for review
August 1, 2026 13:21
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
object(name, forward_range)constructor already excludedstd::string(a range ofchar), but C string literals andstd::string_viewstill 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
StringLikeforstd::string/string_view/const char*/char*StringLikefrom the forward-range array constructorbuilder::valuestring-like inputs asstring_typevector<char>→ integer array behaviorTest plan
./tools/CB.sh debug test --tags='[xson]'(432/432)StringLikeConstructorNotCharArrayregression covers literal,string_view,const char*, assignment, builder, andvector<char>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.
1e23off by 1 ULP) by stoppingbase * std::pow(10, exp)at number completion. The decoder now records the raw number lexeme inm_number_token, thenemit_parsed_number()usesstd::from_charsfor 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 testScientificNotationMatchesFromCharscompares parse results tofrom_chars.Separately,
StringLike(const char*,char*,string_view) is excluded from the forward-range array constructor soobject{"Name","Papa"}and similar no longer become ASCII code arrays (including a trailing NUL). Dedicated constructors, assignment, andbuilder::valuecoerce string-like inputs tostring_type;vector<char>still builds byte arrays. TestStringLikeConstructorNotCharArraycovers this.Reviewed by Cursor Bugbot for commit e8f3be0. Bugbot is set up for automated code reviews on this repo. Configure here.