The C++ standard, [facet.num.get.virtuals], defines the method to be
used for reading numeric values from an iterator. The core loop is
defined thusly in N3242 (the draft for the C++11 standard):
Stage 2: If in==end then stage 2 terminates. Otherwise a charT is
taken from in and local variables are initialized as if by
char_type ct = *in;
char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms];
if (ct == use_facet<numpunct<charT> >(loc).decimal_point())
c = '.';
bool discard =
ct == use_facet<numpunct<charT> >(loc).thousands_sep()
&& use_facet<numpunct<charT> >(loc).grouping().length() != 0;
where the values src and atoms are defined as if by:
static const char src[] = "0123456789abcdefxABCDEFX+-";
char_type atoms[sizeof(src)];
use_facet<ctype<charT> >(loc).widen(src, src + sizeof(src), atoms);
for this value of loc.
If discard is true, then if '.' has not yet been accumulated, then the
position of the character is remembered, but the character is
otherwise ignored. Otherwise, if '.' has already been accumulated, the
character is discarded and Stage 2 terminates.
If the character is either discarded or accumulated then in is
advanced by ++in and processing returns to the beginning of stage 2.
Stage 3: The sequence of chars accumulated in stage 2 (the field) is
converted to a numeric value by the rules of one of the functions
declared in the header <cstdlib>:
- For a signed integer value, the function strtoll.
- For an unsigned integer value, the function strtoull.
- For a floating-point value, the function strtold.
The important part for our purposes here is the line:
char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms];
which implies that we are to accumulate any and all characters that
might be numerical constituents. According to the spec text, we might
accumulate a long run of numeric constituents, only to decide in stage 3
that our accumulated string cannot be a valid number. Please note that
this includes characters like 'x' and 'X' which are only valid as part
of a hexadecimal prefix.
sdp_unittests has a number of tests that look like:
ParseInvalid<SdpImageattrAttributeList::XYRange>("[x", 1);
The test converts the input string to a stringstream, and attempts to
read an integer from the stream starting after the '[' character. The
test expects that no input from the string stream will be consumed, as
the character 'x' cannot begin any number, and thus the position of the
stream after failure will be 1. This behavior is consistent with MSVC's
standard library, libstdc++, and stlport.
However, libc++ uses a different algorithm that appears to hew more
closely to the letter of the spec, and consumes the 'x' character as
being a valid constituent character ("accumulates" in the above text).
The string is rejected as an invalid integer, yet the position of the
string stream afterwards is different from what the test expects, and we
therefore fail.
This patch therefore alters a number of tests to use a different invalid
character, 'v', that both the incremental algorithm (MSVC, libstdc++,
stlport) and the all-at-once algorithm (libc++) will recognize as not
being a valid constituent character and stop the parsing early, as
expected. You might think that specifying the base for numeric input as
std::dec would work, and it partially does, but reading floating-point
numbers still reads the 'x' characters (!).
Be warned. Do not attemp to change the .js "test" source code in ./js
They are meant to check
- the outdated 0666 octal constant is still parsed correctly,
- the outdated 0666 octal constant raises syntax error flag
in strict mode, etc.
So leave them alone.
No WebRTC session statistics will be saved until all PeerConnections
in private browsing window end. In addition, the shared
WebRTC ICE signalling log for that e10s process is disabled until the
private session close.