Skip to content

Commit 7dba9f6

Browse files
Remove unsafe code from CheckText
1 parent 6ebfdef commit 7dba9f6

File tree

1 file changed

+34
-42
lines changed

1 file changed

+34
-42
lines changed

src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3512,63 +3512,55 @@ private XmlNodeType ScanOverAnyValue(BinXmlToken token, bool attr, bool checkCha
35123512
return XmlNodeType.Text;
35133513
}
35143514

3515-
private unsafe XmlNodeType CheckText(bool attr)
3515+
private XmlNodeType CheckText(bool attr)
35163516
{
35173517
Debug.Assert(_checkCharacters, "this.checkCharacters");
3518-
// assert that size is an even number
3519-
Debug.Assert(0 == ((_pos - _tokDataPos) & 1), "Data size should not be odd");
35203518
// grab local copy (perf)
35213519

3522-
fixed (byte* pb = _data)
3523-
{
3524-
int end = _pos;
3525-
int pos = _tokDataPos;
3520+
ReadOnlySpan<byte> data = _data.AsSpan(_tokDataPos, _end - _tokDataPos);
3521+
Debug.Assert(data.Length % 2 == 0, "Data size should not be odd");
35263522

3527-
if (!attr)
3523+
if (!attr)
3524+
{
3525+
// scan if this is whitespace
3526+
while (true)
35283527
{
3529-
// scan if this is whitespace
3530-
while (true)
3531-
{
3532-
int posNext = pos + 2;
3533-
if (posNext > end)
3534-
return _xmlspacePreserve ? XmlNodeType.SignificantWhitespace : XmlNodeType.Whitespace;
3535-
if (pb[pos + 1] != 0 || !XmlCharType.IsWhiteSpace((char)pb[pos]))
3536-
break;
3537-
pos = posNext;
3538-
}
3528+
if (!BinaryPrimitives.TryReadUInt16LittleEndian(data, out ushort value))
3529+
return _xmlspacePreserve ? XmlNodeType.SignificantWhitespace : XmlNodeType.Whitespace;
3530+
if (value > byte.MaxValue || !XmlCharType.IsWhiteSpace((char)value))
3531+
break;
3532+
data = data.Slice(2); // we consumed one ANSI whitespace char
35393533
}
3534+
}
35403535

3536+
while (true)
3537+
{
3538+
char ch;
35413539
while (true)
35423540
{
3543-
char ch;
3544-
while (true)
3545-
{
3546-
int posNext = pos + 2;
3547-
if (posNext > end)
3548-
return XmlNodeType.Text;
3549-
ch = (char)(pb[pos] | ((int)(pb[pos + 1]) << 8));
3550-
if (!XmlCharType.IsCharData(ch))
3551-
break;
3552-
pos = posNext;
3553-
}
3541+
if (!BinaryPrimitives.TryReadUInt16LittleEndian(data, out ushort value))
3542+
return XmlNodeType.Text;
3543+
data = data.Slice(2); // we consumed one char (possibly a high surrogate)
3544+
ch = (char)value;
3545+
if (!XmlCharType.IsCharData(ch))
3546+
break;
3547+
}
35543548

3555-
if (!XmlCharType.IsHighSurrogate(ch))
3549+
if (!XmlCharType.IsHighSurrogate(ch))
3550+
{
3551+
throw XmlConvert.CreateInvalidCharException(ch, '\0', ExceptionType.XmlException);
3552+
}
3553+
else
3554+
{
3555+
if (!BinaryPrimitives.TryReadUInt16LittleEndian(data, out ushort lowSurr))
35563556
{
3557-
throw XmlConvert.CreateInvalidCharException(ch, '\0', ExceptionType.XmlException);
3557+
throw ThrowXmlException(SR.Xml_InvalidSurrogateMissingLowChar);
35583558
}
3559-
else
3559+
if (!XmlCharType.IsLowSurrogate((char)lowSurr))
35603560
{
3561-
if ((pos + 4) > end)
3562-
{
3563-
throw ThrowXmlException(SR.Xml_InvalidSurrogateMissingLowChar);
3564-
}
3565-
char chNext = (char)(pb[pos + 2] | ((int)(pb[pos + 3]) << 8));
3566-
if (!XmlCharType.IsLowSurrogate(chNext))
3567-
{
3568-
throw XmlConvert.CreateInvalidSurrogatePairException(ch, chNext);
3569-
}
3561+
throw XmlConvert.CreateInvalidSurrogatePairException(ch, (char)lowSurr);
35703562
}
3571-
pos += 4;
3563+
data = data.Slice(2); //consumed a low surrogate char
35723564
}
35733565
}
35743566
}

0 commit comments

Comments
 (0)