diff --git a/modules/quercus/src/com/caucho/quercus/env/StringBuilderValue.java b/modules/quercus/src/com/caucho/quercus/env/StringBuilderValue.java index f6c1540..9ed635e 100644 --- a/modules/quercus/src/com/caucho/quercus/env/StringBuilderValue.java +++ b/modules/quercus/src/com/caucho/quercus/env/StringBuilderValue.java @@ -407,6 +407,10 @@ public class StringBuilderValue i++; } + if (i < (len - 2) && buffer[i] == '0' && buffer[i+1] == 'x') { + return (double) parseLong(buffer, offset, len); + } + if (i < len && ((ch = buffer[i]) == '+' || ch == '-')) { i++; } diff --git a/modules/quercus/src/com/caucho/quercus/env/StringValue.java b/modules/quercus/src/com/caucho/quercus/env/StringValue.java index b2f11c8..e6360d5 100644 --- a/modules/quercus/src/com/caucho/quercus/env/StringValue.java +++ b/modules/quercus/src/com/caucho/quercus/env/StringValue.java @@ -346,20 +346,42 @@ abstract public class StringValue offset++; } + int base = 10; while (offset < end) { int ch = buffer[offset++]; + if (ch == 'x' && value == 0) { + // hex encoded number 0xABCD + base = 16; + continue; + } if ('0' <= ch && ch <= '9') { - long newValue = 10 * value + ch - '0'; + long newValue = base * value + ch - '0'; + if (newValue < value) { + // long value overflowed, set result to integer max + result = Integer.MAX_VALUE; + isResultSet = true; + break; + } + value = newValue; + } + else if (base == 16 && 'a' <= ch && ch <= 'f') { + long newValue = base * value + ch - 'a' + 10; if (newValue < value) { - // php/0143 - // long value overflowed result = Integer.MAX_VALUE; isResultSet = true; break; } value = newValue; } + else if (base == 16 && 'A' <= ch && ch <= 'F') { + long newValue = base * value + ch - 'A' + 10; + if (newValue < value) { + result = Integer.MAX_VALUE; + isResultSet = true; + break; + } + } else { result = sign * value; isResultSet = true; @@ -398,11 +420,17 @@ abstract public class StringValue offset++; } + int base = 10; while (offset < end) { int ch = buffer[offset++]; + if (ch == 'x' && value == 0) { + // hex encoded number 0xABCD + base = 16; + continue; + } if ('0' <= ch && ch <= '9') { - long newValue = 10 * value + ch - '0'; + long newValue = base * value + ch - '0'; if (newValue < value) { // long value overflowed, set result to integer max result = Integer.MAX_VALUE; @@ -411,6 +439,24 @@ abstract public class StringValue } value = newValue; } + else if (base == 16 && 'a' <= ch && ch <= 'f') { + long newValue = base * value + ch - 'a' + 10; + if (newValue < value) { + result = Integer.MAX_VALUE; + isResultSet = true; + break; + } + value = newValue; + } + else if (base == 16 && 'A' <= ch && ch <= 'F') { + long newValue = base * value + ch - 'A' + 10; + if (newValue < value) { + result = Integer.MAX_VALUE; + isResultSet = true; + break; + } + value = newValue; + } else { result = sign * value; isResultSet = true; @@ -452,11 +498,17 @@ abstract public class StringValue offset++; } + int base = 10; while (offset < end) { int ch = string.charAt(offset++); + if (ch == 'x' && value == 0) { + // hex encoded number 0xABCD + base = 16; + continue; + } if ('0' <= ch && ch <= '9') { - long newValue = 10 * value + ch - '0'; + long newValue = base * value + ch - '0'; if (newValue < value) { // long value overflowed, set result to integer max result = Integer.MAX_VALUE; @@ -465,6 +517,23 @@ abstract public class StringValue } value = newValue; } + else if (base == 16 && 'a' <= ch && ch <= 'f') { + long newValue = base * value + ch - 'a' + 10; + if (newValue < value) { + result = Integer.MAX_VALUE; + isResultSet = true; + break; + } + value = newValue; + } + else if (base == 16 && 'A' <= ch && ch <= 'F') { + long newValue = base * value + ch - 'A' + 10; + if (newValue < value) { + result = Integer.MAX_VALUE; + isResultSet = true; + break; + } + } else { result = sign * value; isResultSet = true;