Skip to content

Commit 29c3a48

Browse files
author
mgricken
committed
Fixes bugs
2610095: Illegal hexadecimal constants generate meta-errors 2634786: 0l causes NumberFormatException M dynamicjava/src/koala/dynamicjava/tree/IntegerLiteral.java M dynamicjava/src/koala/dynamicjava/tree/LongLiteral.java M dynamicjava/src/koala/dynamicjava/tree/LongLiteralTest.java M drjava/lib/dynamicjava-base.jar M drjava/src/edu/rice/cs/drjava/model/AbstractDJDocumentTest.java M drjava/src/edu/rice/cs/drjava/model/AbstractDJDocument.java git-svn-id: file:///tmp/test-svn/trunk@4773 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent 2666826 commit 29c3a48

File tree

6 files changed

+174
-97
lines changed

6 files changed

+174
-97
lines changed

drjava/lib/dynamicjava-base.jar

-100 Bytes
Binary file not shown.

drjava/src/edu/rice/cs/drjava/model/AbstractDJDocument.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -376,30 +376,40 @@ static boolean _isNum(String x) {
376376
return true;
377377
}
378378
catch (NumberFormatException e) {
379+
int radix = 10;
379380
int begin = 0;
380381
int end = x.length();
382+
int bits = 32;
381383
if (end-begin>1) {
384+
// string is not empty
385+
char ch = x.charAt(end-1);
386+
if ((ch=='l')||(ch=='L')) { // skip trailing 'l' or 'L'
387+
--end;
388+
bits = 64;
389+
}
390+
if (end-begin>1) {
382391
// string is not empty
383-
char ch = x.charAt(end-1);
384-
if ((ch=='l')||(ch=='L')) --end; // skip trailing 'l' or 'L'
385-
if (end-begin>1) {
392+
if (x.charAt(0)=='0') { // skip leading '0' of octal or hexadecimal literal
393+
++begin;
394+
radix = 8;
395+
if (end-begin>1) {
386396
// string is not empty
387-
if (x.charAt(0)=='0') { // skip leading '0' of octal or hexadecimal literal
388-
++begin;
389-
if (end-begin>1) {
390-
// string is not empty
391-
ch = x.charAt(1);
392-
if ((ch=='x')||(ch=='X')) ++begin; // skip 'x' or 'X' from hexadecimal literal
393-
}
397+
ch = x.charAt(1);
398+
if ((ch=='x')||(ch=='X')) { // skip 'x' or 'X' from hexadecimal literal
399+
++begin;
400+
radix = 16;
394401
}
402+
}
395403
}
404+
}
396405
}
397406
try {
398-
Long.parseLong(x.substring(begin,end));
399-
return true;
407+
// BigInteger can parse hex numbers representing negative longs; Long can't
408+
java.math.BigInteger val = new java.math.BigInteger(x.substring(begin, end), radix);
409+
return (val.bitLength() <= bits);
400410
}
401411
catch (NumberFormatException e2) {
402-
return false;
412+
return false;
403413
}
404414
}
405415
}

drjava/src/edu/rice/cs/drjava/model/AbstractDJDocumentTest.java

Lines changed: 116 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -42,81 +42,121 @@
4242
*/
4343
public class AbstractDJDocumentTest extends DrJavaTestCase {
4444
public void testIsNum() {
45-
assertTrue(AbstractDJDocument._isNum("0"));
46-
assertTrue(AbstractDJDocument._isNum("1"));
47-
assertTrue(AbstractDJDocument._isNum("12"));
48-
49-
assertTrue(AbstractDJDocument._isNum("0l"));
50-
assertTrue(AbstractDJDocument._isNum("1l"));
51-
assertTrue(AbstractDJDocument._isNum("12l"));
52-
assertTrue(AbstractDJDocument._isNum("0L"));
53-
assertTrue(AbstractDJDocument._isNum("1L"));
54-
assertTrue(AbstractDJDocument._isNum("12L"));
55-
56-
assertTrue(AbstractDJDocument._isNum("00"));
57-
assertTrue(AbstractDJDocument._isNum("01"));
58-
assertTrue(AbstractDJDocument._isNum("012"));
59-
assertTrue(AbstractDJDocument._isNum("00l"));
60-
assertTrue(AbstractDJDocument._isNum("01l"));
61-
assertTrue(AbstractDJDocument._isNum("012l"));
62-
assertTrue(AbstractDJDocument._isNum("00L"));
63-
assertTrue(AbstractDJDocument._isNum("01L"));
64-
assertTrue(AbstractDJDocument._isNum("012L"));
65-
66-
assertTrue(AbstractDJDocument._isNum("0x0"));
67-
assertTrue(AbstractDJDocument._isNum("0x1"));
68-
assertTrue(AbstractDJDocument._isNum("0x12"));
69-
assertTrue(AbstractDJDocument._isNum("0x0l"));
70-
assertTrue(AbstractDJDocument._isNum("0x1l"));
71-
assertTrue(AbstractDJDocument._isNum("0x12l"));
72-
assertTrue(AbstractDJDocument._isNum("0x0L"));
73-
assertTrue(AbstractDJDocument._isNum("0x1L"));
74-
assertTrue(AbstractDJDocument._isNum("0x12L"));
75-
76-
assertTrue(AbstractDJDocument._isNum("1.0"));
77-
assertTrue(AbstractDJDocument._isNum("12.0"));
78-
assertTrue(AbstractDJDocument._isNum("12.3"));
79-
assertTrue(AbstractDJDocument._isNum("12.34"));
80-
81-
assertTrue(AbstractDJDocument._isNum("1.0f"));
82-
assertTrue(AbstractDJDocument._isNum("12.0f"));
83-
assertTrue(AbstractDJDocument._isNum("12.3f"));
84-
assertTrue(AbstractDJDocument._isNum("12.34f"));
85-
assertTrue(AbstractDJDocument._isNum("1.0F"));
86-
assertTrue(AbstractDJDocument._isNum("12.0F"));
87-
assertTrue(AbstractDJDocument._isNum("12.3F"));
88-
assertTrue(AbstractDJDocument._isNum("12.34F"));
89-
90-
assertTrue(AbstractDJDocument._isNum("1.0d"));
91-
assertTrue(AbstractDJDocument._isNum("12.0d"));
92-
assertTrue(AbstractDJDocument._isNum("12.3d"));
93-
assertTrue(AbstractDJDocument._isNum("12.34d"));
94-
assertTrue(AbstractDJDocument._isNum("1.0D"));
95-
assertTrue(AbstractDJDocument._isNum("12.0D"));
96-
assertTrue(AbstractDJDocument._isNum("12.3D"));
97-
assertTrue(AbstractDJDocument._isNum("12.34D"));
98-
99-
assertTrue(AbstractDJDocument._isNum("1.0e2"));
100-
assertTrue(AbstractDJDocument._isNum("12.0e2"));
101-
assertTrue(AbstractDJDocument._isNum("12.3e2"));
102-
assertTrue(AbstractDJDocument._isNum("12.34e2"));
103-
104-
assertTrue(AbstractDJDocument._isNum("1.0e2f"));
105-
assertTrue(AbstractDJDocument._isNum("12.0e2f"));
106-
assertTrue(AbstractDJDocument._isNum("12.3e2f"));
107-
assertTrue(AbstractDJDocument._isNum("12.34e2f"));
108-
assertTrue(AbstractDJDocument._isNum("1.0e2F"));
109-
assertTrue(AbstractDJDocument._isNum("12.0e2F"));
110-
assertTrue(AbstractDJDocument._isNum("12.3e2F"));
111-
assertTrue(AbstractDJDocument._isNum("12.34e2F"));
112-
113-
assertTrue(AbstractDJDocument._isNum("1.0e2d"));
114-
assertTrue(AbstractDJDocument._isNum("12.0e2d"));
115-
assertTrue(AbstractDJDocument._isNum("12.3e2d"));
116-
assertTrue(AbstractDJDocument._isNum("12.34e2d"));
117-
assertTrue(AbstractDJDocument._isNum("1.0e2D"));
118-
assertTrue(AbstractDJDocument._isNum("12.0e2D"));
119-
assertTrue(AbstractDJDocument._isNum("12.3e2D"));
120-
assertTrue(AbstractDJDocument._isNum("12.34e2D"));
45+
assertTrue(AbstractDJDocument._isNum("0"));
46+
assertTrue(AbstractDJDocument._isNum("1"));
47+
assertTrue(AbstractDJDocument._isNum("12"));
48+
49+
assertTrue(AbstractDJDocument._isNum("0l"));
50+
assertTrue(AbstractDJDocument._isNum("1l"));
51+
assertTrue(AbstractDJDocument._isNum("12l"));
52+
assertTrue(AbstractDJDocument._isNum("0L"));
53+
assertTrue(AbstractDJDocument._isNum("1L"));
54+
assertTrue(AbstractDJDocument._isNum("12L"));
55+
56+
assertTrue(AbstractDJDocument._isNum("00"));
57+
assertTrue(AbstractDJDocument._isNum("01"));
58+
assertTrue(AbstractDJDocument._isNum("012"));
59+
assertTrue(AbstractDJDocument._isNum("00l"));
60+
assertTrue(AbstractDJDocument._isNum("01l"));
61+
assertTrue(AbstractDJDocument._isNum("012l"));
62+
assertTrue(AbstractDJDocument._isNum("00L"));
63+
assertTrue(AbstractDJDocument._isNum("01L"));
64+
assertTrue(AbstractDJDocument._isNum("012L"));
65+
66+
assertTrue(AbstractDJDocument._isNum("0X0"));
67+
assertTrue(AbstractDJDocument._isNum("0X1"));
68+
assertTrue(AbstractDJDocument._isNum("0X12"));
69+
assertTrue(AbstractDJDocument._isNum("0Xff"));
70+
assertTrue(AbstractDJDocument._isNum("0XFF"));
71+
assertTrue(AbstractDJDocument._isNum("0XFFFFFFFF"));
72+
assertFalse(AbstractDJDocument._isNum("0XFFFFFFFFF"));
73+
assertFalse(AbstractDJDocument._isNum("0Xg"));
74+
assertTrue(AbstractDJDocument._isNum("0X0l"));
75+
assertTrue(AbstractDJDocument._isNum("0X1l"));
76+
assertTrue(AbstractDJDocument._isNum("0X12l"));
77+
assertTrue(AbstractDJDocument._isNum("0Xffl"));
78+
assertTrue(AbstractDJDocument._isNum("0XFFl"));
79+
assertTrue(AbstractDJDocument._isNum("0XFFFFFFFFFFFFFFFFl"));
80+
assertFalse(AbstractDJDocument._isNum("0XFFFFFFFFFFFFFFFFFl"));
81+
assertFalse(AbstractDJDocument._isNum("0Xgl"));
82+
assertTrue(AbstractDJDocument._isNum("0X0L"));
83+
assertTrue(AbstractDJDocument._isNum("0X1L"));
84+
assertTrue(AbstractDJDocument._isNum("0X12L"));
85+
assertTrue(AbstractDJDocument._isNum("0XffL"));
86+
assertTrue(AbstractDJDocument._isNum("0XFFL"));
87+
assertFalse(AbstractDJDocument._isNum("0XgL"));
88+
assertTrue(AbstractDJDocument._isNum("0XFFFFFFFFFFFFFFFFL"));
89+
assertFalse(AbstractDJDocument._isNum("0XFFFFFFFFFFFFFFFFFL"));
90+
91+
assertTrue(AbstractDJDocument._isNum("0x0"));
92+
assertTrue(AbstractDJDocument._isNum("0x1"));
93+
assertTrue(AbstractDJDocument._isNum("0x12"));
94+
assertTrue(AbstractDJDocument._isNum("0xff"));
95+
assertTrue(AbstractDJDocument._isNum("0xFF"));
96+
assertTrue(AbstractDJDocument._isNum("0xFFFFFFFF"));
97+
assertFalse(AbstractDJDocument._isNum("0xFFFFFFFFF"));
98+
assertFalse(AbstractDJDocument._isNum("0xg"));
99+
assertTrue(AbstractDJDocument._isNum("0x0l"));
100+
assertTrue(AbstractDJDocument._isNum("0x1l"));
101+
assertTrue(AbstractDJDocument._isNum("0x12l"));
102+
assertTrue(AbstractDJDocument._isNum("0xffl"));
103+
assertTrue(AbstractDJDocument._isNum("0xFFl"));
104+
assertTrue(AbstractDJDocument._isNum("0xFFFFFFFFFFFFFFFFl"));
105+
assertFalse(AbstractDJDocument._isNum("0xFFFFFFFFFFFFFFFFFl"));
106+
assertFalse(AbstractDJDocument._isNum("0xgl"));
107+
assertTrue(AbstractDJDocument._isNum("0x0L"));
108+
assertTrue(AbstractDJDocument._isNum("0x1L"));
109+
assertTrue(AbstractDJDocument._isNum("0x12L"));
110+
assertTrue(AbstractDJDocument._isNum("0xffL"));
111+
assertTrue(AbstractDJDocument._isNum("0xFFL"));
112+
assertFalse(AbstractDJDocument._isNum("0xgL"));
113+
assertTrue(AbstractDJDocument._isNum("0xFFFFFFFFFFFFFFFFL"));
114+
assertFalse(AbstractDJDocument._isNum("0xFFFFFFFFFFFFFFFFFL"));
115+
116+
assertTrue(AbstractDJDocument._isNum("1.0"));
117+
assertTrue(AbstractDJDocument._isNum("12.0"));
118+
assertTrue(AbstractDJDocument._isNum("12.3"));
119+
assertTrue(AbstractDJDocument._isNum("12.34"));
120+
121+
assertTrue(AbstractDJDocument._isNum("1.0f"));
122+
assertTrue(AbstractDJDocument._isNum("12.0f"));
123+
assertTrue(AbstractDJDocument._isNum("12.3f"));
124+
assertTrue(AbstractDJDocument._isNum("12.34f"));
125+
assertTrue(AbstractDJDocument._isNum("1.0F"));
126+
assertTrue(AbstractDJDocument._isNum("12.0F"));
127+
assertTrue(AbstractDJDocument._isNum("12.3F"));
128+
assertTrue(AbstractDJDocument._isNum("12.34F"));
129+
130+
assertTrue(AbstractDJDocument._isNum("1.0d"));
131+
assertTrue(AbstractDJDocument._isNum("12.0d"));
132+
assertTrue(AbstractDJDocument._isNum("12.3d"));
133+
assertTrue(AbstractDJDocument._isNum("12.34d"));
134+
assertTrue(AbstractDJDocument._isNum("1.0D"));
135+
assertTrue(AbstractDJDocument._isNum("12.0D"));
136+
assertTrue(AbstractDJDocument._isNum("12.3D"));
137+
assertTrue(AbstractDJDocument._isNum("12.34D"));
138+
139+
assertTrue(AbstractDJDocument._isNum("1.0e2"));
140+
assertTrue(AbstractDJDocument._isNum("12.0e2"));
141+
assertTrue(AbstractDJDocument._isNum("12.3e2"));
142+
assertTrue(AbstractDJDocument._isNum("12.34e2"));
143+
144+
assertTrue(AbstractDJDocument._isNum("1.0e2f"));
145+
assertTrue(AbstractDJDocument._isNum("12.0e2f"));
146+
assertTrue(AbstractDJDocument._isNum("12.3e2f"));
147+
assertTrue(AbstractDJDocument._isNum("12.34e2f"));
148+
assertTrue(AbstractDJDocument._isNum("1.0e2F"));
149+
assertTrue(AbstractDJDocument._isNum("12.0e2F"));
150+
assertTrue(AbstractDJDocument._isNum("12.3e2F"));
151+
assertTrue(AbstractDJDocument._isNum("12.34e2F"));
152+
153+
assertTrue(AbstractDJDocument._isNum("1.0e2d"));
154+
assertTrue(AbstractDJDocument._isNum("12.0e2d"));
155+
assertTrue(AbstractDJDocument._isNum("12.3e2d"));
156+
assertTrue(AbstractDJDocument._isNum("12.34e2d"));
157+
assertTrue(AbstractDJDocument._isNum("1.0e2D"));
158+
assertTrue(AbstractDJDocument._isNum("12.0e2D"));
159+
assertTrue(AbstractDJDocument._isNum("12.3e2D"));
160+
assertTrue(AbstractDJDocument._isNum("12.34e2D"));
121161
}
122162
}

dynamicjava/src/koala/dynamicjava/tree/IntegerLiteral.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
package koala.dynamicjava.tree;
3030

31+
import koala.dynamicjava.parser.wrapper.ParseError;
32+
3133
import java.math.BigInteger;
3234

3335
/**
@@ -69,15 +71,17 @@ private static Integer parse(String s) {
6971
int radix = 10;
7072
int start = 0;
7173
boolean negate = false;
72-
if (s.startsWith("0x")) { radix = 16; start += 2; }
73-
else if (s.startsWith("0") && s.length() > 1) { radix = 8; start++; }
74-
else if (s.startsWith("-")) { start++; negate = true; }
74+
int end = s.length();
75+
// only consider 0x or 0 or - if this doesn't make the string empty
76+
if ((end-start>1) && (s.startsWith("-"))) { start++; negate = true; }
77+
if ((end-start>2) && (s.startsWith("0x",start))) { radix = 16; start += 2; }
78+
else if ((end-start>1) && (s.startsWith("0",start)) && (s.length() > 1)) { radix = 8; start++; }
7579
// BigInteger can parse hex numbers representing negative ints; Integer can't
7680
BigInteger val = new BigInteger(s.substring(start), radix);
7781
if (negate) { val = val.negate(); }
7882
int result = val.intValue();
7983
if (val.bitLength() > 32 || (radix == 10 && !val.equals(BigInteger.valueOf(result)))) {
80-
throw new NumberFormatException("Literal is out of range");
84+
throw new ParseError(new NumberFormatException("Literal is out of range: "+s));
8185
}
8286
return result;
8387
}

dynamicjava/src/koala/dynamicjava/tree/LongLiteral.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
package koala.dynamicjava.tree;
3030

31+
import koala.dynamicjava.parser.wrapper.ParseError;
32+
3133
import java.math.BigInteger;
3234

3335
/**
@@ -71,15 +73,16 @@ private static Long parse(String s) {
7173
boolean negate = false;
7274
int end = s.length();
7375
if (s.endsWith("l") || s.endsWith("L")) { end--; }
74-
if (s.startsWith("0x")) { radix = 16; start += 2; }
75-
else if (s.startsWith("0") && s.length() > 1) { radix = 8; start++; }
76-
else if (s.startsWith("-")) { start++; negate = true; }
76+
// only consider 0x or 0 or - if this doesn't make the string empty
77+
if ((end-start>1) && (s.startsWith("-"))) { start++; negate = true; }
78+
if ((end-start>2) && (s.startsWith("0x",start))) { radix = 16; start += 2; }
79+
else if ((end-start>1) && (s.startsWith("0",start)) && (s.length() > 1)) { radix = 8; start++; }
7780
// BigInteger can parse hex numbers representing negative longs; Long can't
7881
BigInteger val = new BigInteger(s.substring(start, end), radix);
7982
if (negate) { val = val.negate(); }
8083
long result = val.longValue();
8184
if (val.bitLength() > 64 || (radix == 10 && !val.equals(BigInteger.valueOf(result)))) {
82-
throw new NumberFormatException("Literal is out of range");
85+
throw new ParseError(new NumberFormatException("Literal is out of range: "+s));
8386
}
8487
return result;
8588
}

dynamicjava/src/koala/dynamicjava/tree/LongLiteralTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ public void testLongLiteral()
6161
assertTrue("Parse 0470", new Long("312").compareTo((Long)ll.getValue()) == 0);
6262
ll = new LongLiteral("312");
6363
assertTrue("Parse 312", new Long("312").compareTo((Long)ll.getValue()) == 0);
64+
65+
//Test parse long refactored into JUnit
66+
ll = new LongLiteral("0x138l");
67+
assertTrue("Parse 0x138l", new Long("312").compareTo((Long)ll.getValue()) == 0);
68+
ll = new LongLiteral("0470l");
69+
assertTrue("Parse 0470l", new Long("312").compareTo((Long)ll.getValue()) == 0);
70+
ll = new LongLiteral("312l");
71+
assertTrue("Parse 312l", new Long("312").compareTo((Long)ll.getValue()) == 0);
72+
ll = new LongLiteral("0x138L");
73+
assertTrue("Parse 0x138L", new Long("312").compareTo((Long)ll.getValue()) == 0);
74+
ll = new LongLiteral("0470L");
75+
assertTrue("Parse 0470L", new Long("312").compareTo((Long)ll.getValue()) == 0);
76+
ll = new LongLiteral("312L");
77+
assertTrue("Parse 312L", new Long("312").compareTo((Long)ll.getValue()) == 0);
78+
ll = new LongLiteral("0");
79+
assertTrue("Parse 0", new Long("0").compareTo((Long)ll.getValue()) == 0);
80+
ll = new LongLiteral("0L");
81+
assertTrue("Parse 0L", new Long("0").compareTo((Long)ll.getValue()) == 0);
82+
ll = new LongLiteral("0l");
83+
assertTrue("Parse 0l", new Long("0").compareTo((Long)ll.getValue()) == 0);
6484

6585
//Test parse hexadecimal refactored into JUnit
6686
ll = new LongLiteral("0x0");

0 commit comments

Comments
 (0)