Skip to content

fix: preserve negative zero sign when stringifying values - #22

Open
rajanpanth wants to merge 1 commit into
NaturalIntelligence:mainfrom
rajanpanth:fix/negative-zero-stringify
Open

fix: preserve negative zero sign when stringifying values#22
rajanpanth wants to merge 1 commit into
NaturalIntelligence:mainfrom
rajanpanth:fix/negative-zero-stringify

Conversation

@rajanpanth

Copy link
Copy Markdown

Summary

Every raw-value-to-string conversion in the builder silently drops the sign of -0, corrupting it to 0:

const builder = new XMLBuilder();
builder.build({ a: -0 }); // '<a>0</a>' -- should be '<a>-0</a>'

This affects text values, attribute values, oneListGroup array items, and stopNode raw content — in both preserveOrder modes. XML has no separate int/float syntax, so the sign carries the only signal that a value was a negative float rather than 0, and it's silently lost on a build round trip (e.g. parser.parse(builder.build(x)) no longer matches x for any -0 value).

Root cause: String(val), val.toString(), and '' + val all render JS -0 as "0" — none of them special-case it — and the builder does this raw-to-string conversion at many separate call sites across fxb.js, orderedJs2Xml.js, and util.js.

Changes

  • src/util.js: add a small shared valToStr() helper that special-cases Object.is(val, -0), and use it inside safeComment/safeCdata/escapeAttribute instead of their bare String(val).
  • src/fxb.js / src/orderedJs2Xml.js: replace every ad hoc '' + val / val.toString() / implicit-ToString raw-value stringification with valToStr(), covering: attribute values, text values, oneListGroup array items, and stopNode raw content, in both preserveOrder: false and preserveOrder: true.
  • Tests added alongside each affected code path in spec/j2x_spec.js, spec/j2x_ordered_spec.js, and spec/stopNodes_spec.js (7 new cases total).

Testing

  • Full suite: 136/136 passing (129 pre-existing + 7 new), 1 pre-existing pending spec unrelated to this change.
  • Manually verified every affected path before/after (text, attribute, oneListGroup, stopNode, CDATA, comment — both preserveOrder modes) using a throwaway script, then encoded the cases as committed tests.
  • npm run lint reports the same pre-existing errors with and without this change (unrelated files/lines; confirmed via git stash) — this PR introduces no new lint issues.

Every raw-value-to-string conversion in the builder (String()/toString()/
implicit ToString via concatenation) silently drops the sign of -0,
corrupting it to 0 for both text and attribute values, in both
preserveOrder modes, and in stopNode raw-content paths. XML has no
separate int/float syntax, so this loss is silent and easy to miss on
a parse -> build round trip.

Add a single shared valToStr() helper that special-cases Object.is(val,
-0) and use it at every such conversion site instead of the ad hoc
String(val)/''+val/val.toString() calls.
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.

1 participant