[tcljava-dev] Patch: exception during 'string is ...'
Brought to you by:
mdejong
|
From: Tom P. <tpo...@ny...> - 2003-10-05 19:47:05
|
This patch fixes an exception thrown during 'string is ...', when
a zero length value is compared. E.g.
% string is integer ""
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(String.java:511)
at tcl.lang.StringCmd.cmdProc(StringCmd.java:458)
With the patch, you get:
% string is integer ""
1
% string is integer -strict ""
0
This patch is against the 1.3.1 release code. The patch simply adds an
'else' block at line 359 encompassing the following switch block.
log entry:
* src/jacl/tcl/lang/StringCmd.java: fix StringIndexOutOfBoundsException
during 'string is' processing when value is zero length.
--
Tom Poindexter
tpo...@ny...
http://www.nyx.net/~tpoindex/
--- jacl1.3.1/src/jacl/tcl/lang/StringCmd.java 2003-07-25 02:45:06.000000000 -0600
+++ jacl1.3.1.tp/src/jacl/tcl/lang/StringCmd.java 2003-09-29 15:31:03.000000000 -0600
@@ -355,193 +355,194 @@
if (length1 == 0) {
if (strict) {
result = false;
- }
- }
+ }
+ } else {
- switch (index) {
- case STR_IS_BOOL:
- case STR_IS_TRUE:
- case STR_IS_FALSE: {
- if (obj.getInternalRep() instanceof TclBoolean) {
- if (((index == STR_IS_TRUE) &&
- !TclBoolean.get(interp, obj)) ||
- ((index == STR_IS_FALSE) &&
- TclBoolean.get(interp, obj))) {
- result = false;
- }
- } else {
- try {
- boolean i = TclBoolean.get(null, obj);
- if (((index == STR_IS_TRUE) && !i) ||
- ((index == STR_IS_FALSE) && i)) {
+ switch (index) {
+ case STR_IS_BOOL:
+ case STR_IS_TRUE:
+ case STR_IS_FALSE: {
+ if (obj.getInternalRep() instanceof TclBoolean) {
+ if (((index == STR_IS_TRUE) &&
+ !TclBoolean.get(interp, obj)) ||
+ ((index == STR_IS_FALSE) &&
+ TclBoolean.get(interp, obj))) {
result = false;
}
- } catch (TclException e) {
- result = false;
+ } else {
+ try {
+ boolean i = TclBoolean.get(null, obj);
+ if (((index == STR_IS_TRUE) && !i) ||
+ ((index == STR_IS_FALSE) && i)) {
+ result = false;
+ }
+ } catch (TclException e) {
+ result = false;
+ }
}
- }
- break;
- }
- case STR_IS_DOUBLE: {
- if ((obj.getInternalRep() instanceof TclDouble) ||
- (obj.getInternalRep() instanceof TclInteger)) {
break;
}
+ case STR_IS_DOUBLE: {
+ if ((obj.getInternalRep() instanceof TclDouble) ||
+ (obj.getInternalRep() instanceof TclInteger)) {
+ break;
+ }
- // This is adapted from Tcl_GetDouble
- //
- // The danger in this function is that
- // "12345678901234567890" is an acceptable 'double',
- // but will later be interp'd as an int by something
- // like [expr]. Therefore, we check to see if it looks
- // like an int, and if so we do a range check on it.
- // If strtoul gets to the end, we know we either
- // received an acceptable int, or over/underflow
+ // This is adapted from Tcl_GetDouble
+ //
+ // The danger in this function is that
+ // "12345678901234567890" is an acceptable 'double',
+ // but will later be interp'd as an int by something
+ // like [expr]. Therefore, we check to see if it looks
+ // like an int, and if so we do a range check on it.
+ // If strtoul gets to the end, we know we either
+ // received an acceptable int, or over/underflow
+
+ if (Expression.looksLikeInt(string1, length1, 0)) {
+ char c = string1.charAt(0);
+ int signIx = (c == '-' || c == '+') ? 1 : 0;
+ StrtoulResult res = Util.strtoul(string1, signIx, 0);
+ if (res.index == length1) {
+ if (res.errno == TCL.INTEGER_RANGE) {
+ result = false;
+ failat = -1;
+ }
+ break;
+ }
+ }
- if (Expression.looksLikeInt(string1, length1, 0)) {
char c = string1.charAt(0);
int signIx = (c == '-' || c == '+') ? 1 : 0;
- StrtoulResult res = Util.strtoul(string1, signIx, 0);
- if (res.index == length1) {
- if (res.errno == TCL.INTEGER_RANGE) {
- result = false;
- failat = -1;
- }
- break;
- }
- }
+ StrtodResult res = Util.strtod(string1, signIx);
+ if (res.errno == TCL.DOUBLE_RANGE) {
+ // if (errno == ERANGE), then it was an over/underflow
+ // problem, but in this method, we only want to know
+ // yes or no, so bad flow returns 0 (false) and sets
+ // the failVarObj to the string length.
- char c = string1.charAt(0);
- int signIx = (c == '-' || c == '+') ? 1 : 0;
- StrtodResult res = Util.strtod(string1, signIx);
- if (res.errno == TCL.DOUBLE_RANGE) {
- // if (errno == ERANGE), then it was an over/underflow
- // problem, but in this method, we only want to know
- // yes or no, so bad flow returns 0 (false) and sets
- // the failVarObj to the string length.
-
- result = false;
- failat = -1;
- } else if (res.index == 0) {
- // In this case, nothing like a number was found
-
- result = false;
- failat = 0;
- } else {
- // Go onto SPACE, since we are
- // allowed trailing whitespace
-
- failat = res.index;
- for (int i = res.index; i<length1; i++) {
- if (!Character.isWhitespace(string1.charAt(i))) {
- result = false;
- break;
+ result = false;
+ failat = -1;
+ } else if (res.index == 0) {
+ // In this case, nothing like a number was found
+
+ result = false;
+ failat = 0;
+ } else {
+ // Go onto SPACE, since we are
+ // allowed trailing whitespace
+
+ failat = res.index;
+ for (int i = res.index; i<length1; i++) {
+ if (!Character.isWhitespace(string1.charAt(i))) {
+ result = false;
+ break;
+ }
}
}
- }
- break;
- }
- case STR_IS_INT: {
- if (obj.getInternalRep() instanceof TclInteger) {
- break;
- }
- boolean isInteger = true;
- try {
- TclInteger.get(null, obj);
- } catch (TclException e) {
- isInteger = false;
- }
- if (isInteger) {
break;
}
+ case STR_IS_INT: {
+ if (obj.getInternalRep() instanceof TclInteger) {
+ break;
+ }
+ boolean isInteger = true;
+ try {
+ TclInteger.get(null, obj);
+ } catch (TclException e) {
+ isInteger = false;
+ }
+ if (isInteger) {
+ break;
+ }
- char c = string1.charAt(0);
- int signIx = (c == '-' || c == '+') ? 1 : 0;
- StrtoulResult res = Util.strtoul(string1, signIx, 0);
- if (res.errno == TCL.INTEGER_RANGE) {
- // if (errno == ERANGE), then it was an over/underflow
- // problem, but in this method, we only want to know
- // yes or no, so bad flow returns false and sets
- // the failVarObj to the string length.
-
- result = false;
- failat = -1;
- } else if (res.index == 0) {
- // In this case, nothing like a number was found
-
- result = false;
- failat = 0;
- } else {
- // Go onto SPACE, since we are
- // allowed trailing whitespace
-
- failat = res.index;
- for (int i = res.index; i<length1; i++) {
- if (!Character.isWhitespace(string1.charAt(i))) {
- result = false;
- break;
+ char c = string1.charAt(0);
+ int signIx = (c == '-' || c == '+') ? 1 : 0;
+ StrtoulResult res = Util.strtoul(string1, signIx, 0);
+ if (res.errno == TCL.INTEGER_RANGE) {
+ // if (errno == ERANGE), then it was an over/underflow
+ // problem, but in this method, we only want to know
+ // yes or no, so bad flow returns false and sets
+ // the failVarObj to the string length.
+
+ result = false;
+ failat = -1;
+ } else if (res.index == 0) {
+ // In this case, nothing like a number was found
+
+ result = false;
+ failat = 0;
+ } else {
+ // Go onto SPACE, since we are
+ // allowed trailing whitespace
+
+ failat = res.index;
+ for (int i = res.index; i<length1; i++) {
+ if (!Character.isWhitespace(string1.charAt(i))) {
+ result = false;
+ break;
+ }
}
}
+ break;
}
- break;
- }
- default: {
- for (failat = 0; failat < length1; failat++) {
- char c = string1.charAt(failat);
- switch (index) {
- case STR_IS_ASCII:
- // This is a valid check in unicode, because
- // all bytes < 0xC0 are single byte chars
- // (but isascii limits that def'n to 0x80).
-
- result = c < 0x80;
- break;
- case STR_IS_ALNUM:
- result = Character.isLetterOrDigit(c);
- break;
- case STR_IS_ALPHA:
- result = Character.isLetter(c);
- break;
- case STR_IS_DIGIT:
- result = Character.isDigit(c);
- break;
- case STR_IS_GRAPH:
- result = ((1 << Character.getType(c))
- & PRINT_BITS) != 0
- && c != ' ';
- break;
- case STR_IS_PRINT:
- result = ((1 << Character.getType(c))
- & PRINT_BITS) != 0;
- break;
- case STR_IS_PUNCT:
- result = ((1 << Character.getType(c))
- & PUNCT_BITS) != 0;
- break;
- case STR_IS_UPPER:
- result = Character.isUpperCase(c);
- break;
- case STR_IS_SPACE:
- result = Character.isWhitespace(c);
- break;
- case STR_IS_CONTROL:
- result = Character.isISOControl(c);
- break;
- case STR_IS_LOWER:
- result = Character.isLowerCase(c);
- break;
- case STR_IS_WORD:
- result = ((1 << Character.getType(c))
- & WORD_BITS) != 0;
- break;
- case STR_IS_XDIGIT:
- result = Character.digit(c, 16) >= 0;
+ default: {
+ for (failat = 0; failat < length1; failat++) {
+ char c = string1.charAt(failat);
+ switch (index) {
+ case STR_IS_ASCII:
+ // This is a valid check in unicode, because
+ // all bytes < 0xC0 are single byte chars
+ // (but isascii limits that def'n to 0x80).
+
+ result = c < 0x80;
+ break;
+ case STR_IS_ALNUM:
+ result = Character.isLetterOrDigit(c);
+ break;
+ case STR_IS_ALPHA:
+ result = Character.isLetter(c);
+ break;
+ case STR_IS_DIGIT:
+ result = Character.isDigit(c);
+ break;
+ case STR_IS_GRAPH:
+ result = ((1 << Character.getType(c))
+ & PRINT_BITS) != 0
+ && c != ' ';
+ break;
+ case STR_IS_PRINT:
+ result = ((1 << Character.getType(c))
+ & PRINT_BITS) != 0;
+ break;
+ case STR_IS_PUNCT:
+ result = ((1 << Character.getType(c))
+ & PUNCT_BITS) != 0;
+ break;
+ case STR_IS_UPPER:
+ result = Character.isUpperCase(c);
+ break;
+ case STR_IS_SPACE:
+ result = Character.isWhitespace(c);
+ break;
+ case STR_IS_CONTROL:
+ result = Character.isISOControl(c);
+ break;
+ case STR_IS_LOWER:
+ result = Character.isLowerCase(c);
+ break;
+ case STR_IS_WORD:
+ result = ((1 << Character.getType(c))
+ & WORD_BITS) != 0;
+ break;
+ case STR_IS_XDIGIT:
+ result = Character.digit(c, 16) >= 0;
+ break;
+ default:
+ throw new TclRuntimeError("unimplemented");
+ }
+ if (!result) {
break;
- default:
- throw new TclRuntimeError("unimplemented");
- }
- if (!result) {
- break;
+ }
}
}
}
|