Commit 41b8fbe
committed
fix(xml,xml-linq): reject code points outside XML's Char production (#2349)
Split from #2085, which repaired the NUL truncation and left this policy open.
Measured: 28 of the 29 non-Char bytes in 0x00-0x1F were EMITTED RAW at every writer
content door and every Xml.Linq direct door, so the emitted document was not
well-formed XML.
THE TICKET RECORDED FIVE PRICED OPTIONS AND CALLED IT A USER DECISION. The blocker
was that /rv was absent. The reference collapses the table to one:
if (_checkCharacters) throw XmlConvert.CreateInvalidCharException((char)ch, '\0');
else { ... entitize or write raw ... } -- XmlEncodedRawTextWriter.cs:1635-1653
with CheckCharacters defaulting to true (XmlWriterSettings.cs:513). .NET rejects by
default and the flag is what turns that off. That is option B, DERIVED rather than
chosen, and SA-5 covers it.
BOTH OF THE TICKET'S PRICING COMPLICATIONS ARE DISSOLVED, NOT ACCEPTED.
1. It priced enforcement on XmlConvert::VerifyXmlChars, which iterates `char` and
so checks BYTES -- it accepts U+FFFE, U+FFFF and a lone surrogate encoded in
UTF-8, all genuinely outside Char, so "enforce with the validator we already
ship" would have bought C0 controls only. Ticket #2354, EARLIER THE SAME DAY,
moved a code-point decoder into Core.Base, and both modules/xml and
modules/xml-linq already depend on it. The correct check now costs one call and
no new component edge; the graph stays at 41 modules / 93 edges.
2. It priced option B as "not a same-shaped change on both sides", because
XNode::SerializeTo takes no settings and SaveOptions has no such value. .NET'S
DO NOT EITHER: XNode.GetXmlWriterSettings constructs a DEFAULT
XmlWriterSettings and touches only Indent and NamespaceHandling
(XNode.cs:681-687), inheriting CheckCharacters = true. So the Linq side needs no
settings channel, no new SaveOptions value and no ambient default -- it checks
unconditionally, and the two door families agree BY CONSTRUCTION rather than by
coordination. That was the whole reason this looked like two changes.
TWO EXCEPTION TYPES, DELIBERATELY. NUL keeps XmlException, because that is this
port's own truncation guard (#2085) -- a length boundary at the tinyxml2 const char*
API, not a transcription of a .NET check. Every other non-Char code point raises
ArgumentException, because that is what XmlConvert.CreateInvalidCharException
produces (XmlConvert.cs:1614-1622), carrying .NET's text.
WHAT IS STILL OPEN IS STATED RATHER THAN LEFT IMPLICIT. XmlReaderSettings
::CheckCharacters also defaults true and is also unenforced, and this port's reader
ACCEPTS these characters -- so writing and reading now disagree. Options A, B and D
all leave that asymmetry and only C and E avoid it. .NET has none, because its
reader enforces too; the reader here is tinyxml2, which this port does not drive
character by character, so closing it is not a matter of adding a call.
Both scope pins are UPDATED, not deleted, exactly as the ticket anticipated:
NonNulControlCharacters_StillEmitted_PinnedScopeBoundary and
NonNulControlCharacters_StillEmittedByTheDirectDoor become Fix2349_* on the same
inputs. Two cases replacing two, so the count does not move.
Four mutations, all caught, each at BOTH door families: the check goes byte-wise
again; U+FFFE and U+FFFF become Char; tab/LF/CR stop being Char; the C0 controls
become Char.
Downstream: neither cna nor mobile-eggbert references XmlWriter, XDocument or
XElement -- zero sites in both.
Gate: 17,333 run, 17,333 passed, 0 failed, 0 skipped across 38 executables, GREEN.
Module boundaries valid (41 modules, 93 edges).
docs/Migration-XmlCheckCharacters.md1 parent b43e72a commit 41b8fbe
8 files changed
Lines changed: 301 additions & 37 deletions
File tree
- docs
- modules
- xml-linq
- include/System/Xml/Linq/detail
- tests/System/Xml/Linq
- xml
- include/System/Xml/detail
- src/System/Xml
- tests/System/Xml
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
Lines changed: 20 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
| |||
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
58 | 72 | | |
59 | 73 | | |
60 | 74 | | |
Lines changed: 26 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| 55 | + | |
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
| |||
334 | 335 | | |
335 | 336 | | |
336 | 337 | | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
342 | | - | |
343 | | - | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
348 | | - | |
349 | | - | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
350 | 359 | | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
351 | 364 | | |
352 | 365 | | |
353 | 366 | | |
| |||
Lines changed: 69 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
6 | 9 | | |
7 | 10 | | |
8 | 11 | | |
| |||
166 | 169 | | |
167 | 170 | | |
168 | 171 | | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
| 172 | + | |
| 173 | + | |
174 | 174 | | |
175 | 175 | | |
176 | 176 | | |
177 | 177 | | |
178 | 178 | | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
179 | 243 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
56 | 72 | | |
57 | 73 | | |
58 | 74 | | |
| |||
0 commit comments