- Notifications
You must be signed in to change notification settings - Fork 527
fix of overflow detection for numeric primitive types #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
| @@ -487,48 +487,56 @@ public final static int readStringSlowPath(JsonIterator iter, int j) throws IOEx | |
} | ||
} | ||
| ||
static long readLongSlowPath(JsonIterator iter, long value) throws IOException { | ||
static long readLongSlowPath(final JsonIterator iter, long value, final boolean negative) throws IOException { | ||
value = -value; // add negatives to avoid redundant checks for Long.MIN_VALUE on each iteration | ||
long limit = negative ? Long.MIN_VALUE : -Long.MAX_VALUE; | ||
long multmin = -922337203685477580L; // limit / 10 | ||
for (; ; ) { | ||
for (int i = iter.head; i < iter.tail; i++) { | ||
int ind = IterImplNumber.intDigits[iter.buf[i]]; | ||
if (ind == IterImplNumber.INVALID_CHAR_FOR_NUMBER) { | ||
iter.head = i; | ||
return value; | ||
return negative ? value : -value; | ||
} | ||
if (value == Long.MIN_VALUE) { | ||
throw iter.reportError("readLongSlowPath", "value is too large for long"); | ||
if (value < multmin) { | ||
throw iter.reportError("readIntSlowPath", "value is too large for int"); | ||
| ||
} | ||
value = (value << 3) + (value << 1) + ind; | ||
if (value < 0 && value != Long.MIN_VALUE) { | ||
value = (value << 3) + (value << 1); | ||
if (value < limit + ind) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. may be we can change if (value < limit + ind) { throw iter.reportError("readLongSlowPath", "value is too large for long"); } value -= ind; to value -= ind; if (value >= 0) { throw iter.reportError("readLongSlowPath", "value is too large for long"); } if value is positive, we add additional There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
| ||
throw iter.reportError("readLongSlowPath", "value is too large for long"); | ||
} | ||
value -= ind; | ||
} | ||
if (!IterImpl.loadMore(iter)) { | ||
iter.head = iter.tail; | ||
return value; | ||
return negative ? value : -value; | ||
} | ||
} | ||
} | ||
| ||
static int readIntSlowPath(JsonIterator iter, int value) throws IOException { | ||
static int readIntSlowPath(final JsonIterator iter, int value, final boolean negative) throws IOException { | ||
value = -value; // add negatives to avoid redundant checks for Integer.MIN_VALUE on each iteration | ||
int limit = negative ? Integer.MIN_VALUE : -Integer.MAX_VALUE; | ||
int multmin = -214748364; // limit / 10 | ||
for (; ; ) { | ||
for (int i = iter.head; i < iter.tail; i++) { | ||
int ind = IterImplNumber.intDigits[iter.buf[i]]; | ||
if (ind == IterImplNumber.INVALID_CHAR_FOR_NUMBER) { | ||
iter.head = i; | ||
return value; | ||
return negative ? value : -value; | ||
} | ||
if (value == Integer.MIN_VALUE) { | ||
if (value < multmin) { | ||
throw iter.reportError("readIntSlowPath", "value is too large for int"); | ||
} | ||
value = (value << 3) + (value << 1) + ind; | ||
if (value < 0 && value != Integer.MIN_VALUE) { | ||
value = (value << 3) + (value << 1); | ||
if (value < limit + ind) { | ||
throw iter.reportError("readIntSlowPath", "value is too large for int"); | ||
} | ||
value -= ind; | ||
} | ||
if (!IterImpl.loadMore(iter)) { | ||
iter.head = iter.tail; | ||
return value; | ||
return negative ? value : -value; | ||
} | ||
} | ||
} | ||
| @@ -582,34 +590,33 @@ public static final String readNumber(final JsonIterator iter) throws IOExceptio | |
} | ||
} | ||
| ||
| ||
static final double readPositiveDouble(final JsonIterator iter) throws IOException { | ||
return readDoubleSlowPath(iter); | ||
static final double readDouble(final JsonIterator iter, final boolean negative) throws IOException { | ||
double result = readDoubleSlowPath(iter); | ||
return negative ? -result : result; | ||
} | ||
| ||
| ||
static final long readPositiveLong(final JsonIterator iter, byte c) throws IOException { | ||
static final long readLong(final JsonIterator iter, final byte c, final boolean negative) throws IOException { | ||
long ind = IterImplNumber.intDigits[c]; | ||
if (ind == 0) { | ||
assertNotLeadingZero(iter); | ||
return 0; | ||
} | ||
if (ind == IterImplNumber.INVALID_CHAR_FOR_NUMBER) { | ||
throw iter.reportError("readPositiveLong", "expect 0~9"); | ||
throw iter.reportError("readLong", "expect 0~9"); | ||
} | ||
return IterImplForStreaming.readLongSlowPath(iter, ind); | ||
return IterImplForStreaming.readLongSlowPath(iter, ind, negative); | ||
} | ||
| ||
static final int readPositiveInt(final JsonIterator iter, byte c) throws IOException { | ||
static final int readInt(final JsonIterator iter, final byte c, final boolean negative) throws IOException { | ||
int ind = IterImplNumber.intDigits[c]; | ||
if (ind == 0) { | ||
assertNotLeadingZero(iter); | ||
return 0; | ||
} | ||
if (ind == IterImplNumber.INVALID_CHAR_FOR_NUMBER) { | ||
throw iter.reportError("readPositiveInt", "expect 0~9"); | ||
throw iter.reportError("readInt", "expect 0~9"); | ||
} | ||
return IterImplForStreaming.readIntSlowPath(iter, ind); | ||
return IterImplForStreaming.readIntSlowPath(iter, ind, negative); | ||
} | ||
| ||
static void assertNotLeadingZero(JsonIterator iter) throws IOException { | ||
| @@ -620,7 +627,7 @@ static void assertNotLeadingZero(JsonIterator iter) throws IOException { | |
if (ind2 == IterImplNumber.INVALID_CHAR_FOR_NUMBER) { | ||
return; | ||
} | ||
throw iter.reportError("readPositiveInt", "leading zero is invalid"); | ||
throw iter.reportError("assertNotLeadingZero", "leading zero is invalid"); | ||
} catch (ArrayIndexOutOfBoundsException e) { | ||
iter.head = iter.tail; | ||
return; | ||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final boolean negative
is not necessary. we can always return negative number, and make it positive from the readLong. this way saved one branch.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some additional param is required until we inline these slow path methods or split them on pair of methods (one for negative, other for positive)