Skip to content

Commit d8e8b42

Browse files
authored
Merge pull request #30 from diffblue/smowton/feature/parseint-exceptions
Fix exception handling in parseInt, parseLong
2 parents 31df88c + ee97592 commit d8e8b42

File tree

3 files changed

+27
-87
lines changed

3 files changed

+27
-87
lines changed

src/main/java/java/lang/Integer.java

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -410,51 +410,7 @@ public static int parseInt(String s, int radix)
410410
" greater than Character.MAX_RADIX");
411411
}
412412

413-
if (radix == 10) {
414-
return parseInt(s);
415-
}
416-
417-
//TODO from here on
418-
int result = 0;
419-
boolean negative = false;
420-
int i = 0, len = s.length();
421-
int limit = -Integer.MAX_VALUE;
422-
int multmin;
423-
int digit;
424-
425-
if (len > 0) {
426-
char firstChar = CProverString.charAt(s, 0);
427-
if (firstChar < '0') { // Possible leading "+" or "-"
428-
if (firstChar == '-') {
429-
negative = true;
430-
limit = Integer.MIN_VALUE;
431-
} else if (firstChar != '+')
432-
throw NumberFormatException.forInputString(s);
433-
434-
if (len == 1) // Cannot have lone "+" or "-"
435-
throw NumberFormatException.forInputString(s);
436-
i++;
437-
}
438-
multmin = limit / radix;
439-
while (i < len) {
440-
// Accumulating negatively avoids surprises near MAX_VALUE
441-
digit = Character.digit(CProverString.charAt(s, i++), radix);
442-
if (digit < 0) {
443-
throw NumberFormatException.forInputString(s);
444-
}
445-
if (result < multmin) {
446-
throw NumberFormatException.forInputString(s);
447-
}
448-
result *= radix;
449-
if (result < limit + digit) {
450-
throw NumberFormatException.forInputString(s);
451-
}
452-
result -= digit;
453-
}
454-
} else {
455-
throw NumberFormatException.forInputString(s);
456-
}
457-
return negative ? result : -result;
413+
return CProverString.parseInt(s, radix);
458414
}
459415

460416
/**
@@ -475,7 +431,11 @@ public static int parseInt(String s, int radix)
475431
* parsable integer.
476432
*/
477433
public static int parseInt(String s) throws NumberFormatException {
478-
return CProver.nondetInt(); //The function is handled by cbmc internally
434+
if (s == null) {
435+
throw new NumberFormatException("null");
436+
}
437+
438+
return CProverString.parseInt(s, 10);
479439
}
480440

481441
/**

src/main/java/java/lang/Long.java

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -474,46 +474,7 @@ public static long parseLong(String s, int radix)
474474
" greater than Character.MAX_RADIX");
475475
}
476476

477-
long result = 0;
478-
boolean negative = false;
479-
int i = 0, len = s.length();
480-
long limit = -Long.MAX_VALUE;
481-
long multmin;
482-
int digit;
483-
484-
if (len > 0) {
485-
char firstChar = CProverString.charAt(s, 0);
486-
if (firstChar < '0') { // Possible leading "+" or "-"
487-
if (firstChar == '-') {
488-
negative = true;
489-
limit = Long.MIN_VALUE;
490-
} else if (firstChar != '+')
491-
throw NumberFormatException.forInputString(s);
492-
493-
if (len == 1) // Cannot have lone "+" or "-"
494-
throw NumberFormatException.forInputString(s);
495-
i++;
496-
}
497-
multmin = limit / radix;
498-
while (i < len) {
499-
// Accumulating negatively avoids surprises near MAX_VALUE
500-
digit = Character.digit(CProverString.charAt(s, i++), radix);
501-
if (digit < 0) {
502-
throw NumberFormatException.forInputString(s);
503-
}
504-
if (result < multmin) {
505-
throw NumberFormatException.forInputString(s);
506-
}
507-
result *= radix;
508-
if (result < limit + digit) {
509-
throw NumberFormatException.forInputString(s);
510-
}
511-
result -= digit;
512-
}
513-
} else {
514-
throw NumberFormatException.forInputString(s);
515-
}
516-
return negative ? result : -result;
477+
return CProverString.parseLong(s, radix);
517478
}
518479

519480
/**
@@ -541,7 +502,10 @@ public static long parseLong(String s, int radix)
541502
* parsable {@code long}.
542503
*/
543504
public static long parseLong(String s) throws NumberFormatException {
544-
return CProver.nondetLong(); //The function is handled by cbmc internally
505+
if (s == null) {
506+
throw new NumberFormatException("null");
507+
}
508+
return CProverString.parseLong(s, 10);
545509
}
546510

547511
/**

src/main/java/org/cprover/CProverString.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,4 +440,20 @@ public static String toString(float f) {
440440
public static String toString(double d) {
441441
return toString(CProver.doubleToFloat(d));
442442
}
443+
444+
/**
445+
* Exactly as Integer.parseInt, except s is already checked non-null and the
446+
* radix is already checked in-range.
447+
*/
448+
public static int parseInt(String s, int radix) {
449+
return CProver.nondetInt();
450+
}
451+
452+
/**
453+
* Exactly as Long.parseLong, except s is already checked non-null and the
454+
* radix is already checked in-range.
455+
*/
456+
public static long parseLong(String s, int radix) {
457+
return CProver.nondetLong();
458+
}
443459
}

0 commit comments

Comments
 (0)