Browse Source

Fixed forum-17502: exception in C# and VB lexer when a hexadecimal literal is larger than ulong.MaxValue.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.1@2559 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
6331df6b0c
  1. 6
      src/Libraries/NRefactory/NRefactory.sln
  2. 8
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Lexer.cs
  3. 84
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  4. 4
      src/Libraries/NRefactory/Test/Lexer/CSharp/NumberLexerTest.cs
  5. 32
      src/Libraries/NRefactory/Test/Lexer/VBNet/LiteralsTests.cs

6
src/Libraries/NRefactory/NRefactory.sln

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# SharpDevelop 2.1.0.1865

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
# SharpDevelop 2.2.0.2532
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryTests", "Test\NRefactoryTests.csproj", "{870115DD-960A-4406-A6B9-600BCDC36A03}"

8
src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Lexer.cs

@ -289,7 +289,13 @@ namespace ICSharpCode.NRefactory.Parser.CSharp @@ -289,7 +289,13 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
// Try to determine a parsable value using ranges. (Quick hack!)
double d = 0;
if (ishex) {
d = ulong.Parse(digit, NumberStyles.HexNumber);
ulong result;
if (ulong.TryParse(digit, NumberStyles.HexNumber, null, out result)) {
d = result;
} else {
errors.Error(y, x, String.Format("Can't parse hexadecimal constant {0}", digit));
return new Token(Tokens.Literal, x, y, stringValue.ToString(), 0);
}
} else {
if (!Double.TryParse(digit, NumberStyles.Integer, null, out d)) {
errors.Error(y, x, String.Format("Can't parse integral constant {0}", digit));

84
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs

@ -12,7 +12,7 @@ using System.Text; @@ -12,7 +12,7 @@ using System.Text;
namespace ICSharpCode.NRefactory.Parser.VB
{
internal class Lexer : AbstractLexer
internal sealed class Lexer : AbstractLexer
{
bool lineEnd = true;
@ -318,6 +318,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -318,6 +318,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
ch = Char.ToUpper(ch, CultureInfo.InvariantCulture);
bool unsigned = ch == 'U';
if (unsigned) {
ReaderRead(); // read the U
ch = (char)ReaderPeek();
sb.Append(ch);
ch = Char.ToUpper(ch, CultureInfo.InvariantCulture);
@ -325,60 +326,65 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -325,60 +326,65 @@ namespace ICSharpCode.NRefactory.Parser.VB
errors.Error(Line, Col, "Invalid type character: U" + ch);
}
}
if (isokt) {
ReaderRead();
ulong number = 0L;
for (int i = 0; i < digit.Length; ++i) {
number = number * 8 + digit[i] - '0';
try {
if (isokt) {
ReaderRead();
ulong number = 0L;
for (int i = 0; i < digit.Length; ++i) {
number = number * 8 + digit[i] - '0';
}
if (ch == 'S') {
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (ushort)number);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (short)number);
} else if (ch == '%' || ch == 'I') {
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (uint)number);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (int)number);
} else if (ch == '&' || ch == 'L') {
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (ulong)number);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (long)number);
} else {
if (number > uint.MaxValue) {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((long)number));
} else {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((int)number));
}
}
}
if (ch == 'S') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (ushort)number);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (short)number);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ch == '%' || ch == 'I') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (uint)number);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (int)number);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ch == '&' || ch == 'L') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (ulong)number);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (long)number);
} else {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ishex) {
ulong number = UInt64.Parse(digit, NumberStyles.HexNumber);
if (number > uint.MaxValue) {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((long)number));
} else {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((int)number));
}
}
}
if (ch == 'S') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ch == '%' || ch == 'I') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ch == '&' || ch == 'L') {
ReaderRead();
if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ishex) {
ulong number = UInt64.Parse(digit, NumberStyles.HexNumber);
if (number > uint.MaxValue) {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((long)number));
} else {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((int)number));
}
} catch (OverflowException ex) {
errors.Error(Line, Col, ex.Message);
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), 0);
}
}
Token nextToken = null; // if we accedently read a 'dot'

4
src/Libraries/NRefactory/Test/Lexer/CSharp/NumberLexerTest.cs

@ -37,6 +37,7 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.CSharp @@ -37,6 +37,7 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.CSharp
Assert.AreEqual(Tokens.Literal, t.kind, "Tokens.Literal");
Assert.AreEqual(text, t.val, "value");
Assert.IsNotNull(t.literalValue, "literalValue is null");
Assert.AreEqual(val.GetType(), t.literalValue.GetType(), "literalValue.GetType()");
Assert.AreEqual(val, t.literalValue, "literalValue");
}
@ -80,12 +81,15 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.CSharp @@ -80,12 +81,15 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.CSharp
GenerateLexer(new StringReader("0xG2F")).NextToken();
// SD2-457
GenerateLexer(new StringReader("0x")).NextToken();
// hexadecimal integer >ulong.MaxValue
GenerateLexer(new StringReader("0xfedcba98765432100")).NextToken();
}
[Test]
public void TestLongHexadecimalInteger()
{
CheckToken("0x4244636f446c6d58", 0x4244636f446c6d58);
CheckToken("0xf244636f446c6d58", 0xf244636f446c6d58);
}
[Test]

32
src/Libraries/NRefactory/Test/Lexer/VBNet/LiteralsTests.cs

@ -37,6 +37,7 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB @@ -37,6 +37,7 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
Token t = GetSingleToken(text);
Assert.AreEqual(tokenType, t.kind, "Tokens.Literal");
Assert.IsNotNull(t.literalValue, "literalValue is null");
Assert.AreEqual(val.GetType(), t.literalValue.GetType(), "literalValue.GetType()");
Assert.AreEqual(val, t.literalValue, "literalValue");
}
@ -63,8 +64,35 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB @@ -63,8 +64,35 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
public void TestHexadecimalInteger()
{
CheckToken("&H10", Tokens.LiteralInteger, 0x10);
CheckToken("&H10&", Tokens.LiteralInteger, 0x10);
CheckToken("&h3ff&", Tokens.LiteralInteger, 0x3ff);
CheckToken("&H10&", Tokens.LiteralInteger, (long)0x10);
CheckToken("&h3ff%", Tokens.LiteralInteger, 0x3ff);
CheckToken("&h8000s", Tokens.LiteralInteger, short.MinValue);
CheckToken("&h8000us", Tokens.LiteralInteger, (ushort)0x8000);
CheckToken("&HffffFFFF", Tokens.LiteralInteger, -1);
CheckToken("&HffffFFFF%", Tokens.LiteralInteger, -1);
CheckToken("&HffffFFFFui", Tokens.LiteralInteger, uint.MaxValue);
CheckToken("&HffffFFFF&", Tokens.LiteralInteger, (long)uint.MaxValue);
}
[Test]
public void TestLongHexadecimalInteger()
{
CheckToken("&H4244636f446c6d58", Tokens.LiteralInteger, 0x4244636f446c6d58);
CheckToken("&hf244636f446c6d58", Tokens.LiteralInteger, -989556688574190248);
CheckToken("&hf244636f446c6d58&", Tokens.LiteralInteger, -989556688574190248);
CheckToken("&hf244636f446c6d58ul", Tokens.LiteralInteger, 0xf244636f446c6d58);
}
[Test]
public void InvalidHexadecimalInteger()
{
// just check that we don't get exceptions:
GenerateLexer(new StringReader("&H")).NextToken();
// >ulong.MaxValue
GenerateLexer(new StringReader("&hff244636f446c6d58")).NextToken();
// needs an ulong, but "i" postfix specified integer
GenerateLexer(new StringReader("&hf244636f446c6d58i")).NextToken();
GenerateLexer(new StringReader("&hf244636f446c6d58ui")).NextToken();
}
[Test]

Loading…
Cancel
Save