Encoder hardening - #102
Open
alexejk wants to merge 2 commits into
Open
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
alexejk
force-pushed
the
encoder-hardening
branch
from
August 31, 2026 15:04
dcfb8e3 to
d208e34
Compare
alexejk
force-pushed
the
encoder-hardening
branch
from
August 31, 2026 15:16
d208e34 to
89f1330
Compare
alexejk
force-pushed
the
encoder-hardening
branch
2 times, most recently
from
August 31, 2026 15:36
84e360b to
75f8a72
Compare
All encoder output now goes through a small xmlWriter that latches the first write error and escapes character data. This closes two gaps: * Method names, struct member names (including xmlrpc tags) and map keys were written raw, so any of them containing & or < produced malformed XML. * Most writes discarded their error, so a failing writer could yield a nil error from Encode with a truncated request already sent. Values controlled by the package use raw(), anything supplied by the caller goes through element()/text() and is escaped.
Doubles were formatted with %f, which pads to six decimal places and silently loses everything beyond it: 0.1234567890123 went out as 0.123457, and both 1e-10 and 1e-300 became 0.000000. Values now use the shortest decimal representation that round-trips exactly and satisfies the specification. The specification allows only decimal point notation - "a plus or a minus, followed by any number of numeric characters, followed by a period and any number of numeric characters" - so exponent notation is avoided and a period is always present, including for whole numbers. NaN and infinities have no representation per the same section of the specification, and previously went on the wire as NaN/+Inf/-Inf, which no receiver can read as a number. They are now rejected with an error.
alexejk
force-pushed
the
encoder-hardening
branch
from
August 31, 2026 16:01
75f8a72 to
a632f79
Compare
|
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.



This PR fixes a couple of encoder defects
Malformed XML from unescaped names.
Method names, struct member names (including
xmlrpctags) and map keys were written raw, so any&or<produced a document the server can't parse. Map keys are the sharpest case, since they can carry data from outside the program.Silent precision loss on doubles.
%fpads to six decimals and drops the rest:0.1234567890123went out as0.123457, and both1e-10and1e-300became0.000000. Values now use the shortest representation that round-trips exactly — no exponent, always a decimal point, per the spec's grammar. NaN and infinities have no representation in the spec and are now rejected rather than emitted asNaN/+Inf.Output goes through a small
xmlWriterutility that escapes character data and latches the first write error. Previously most writes discarded their error, so a failing writer could return nil fromEncodewith a truncated request already sent.Public API unchanged. Wire format change: doubles are shorter (
3.14, not3.140000) - same values, fewer digits.Stack created with GitHub Stacks CLI • Give Feedback 💬