8147500: The HashtableTextDump::get_num() should check for integer overflow
Summary: Add check for integer overflow in HashtableTextDump::get_num()
Reviewed-by: dholmes, iklam
--- a/hotspot/src/share/vm/classfile/compactHashtable.cpp Thu Jan 28 02:30:57 2016 +0100
+++ b/hotspot/src/share/vm/classfile/compactHashtable.cpp Wed Jan 27 22:39:03 2016 -0500
@@ -365,14 +365,14 @@
}
int HashtableTextDump::skip(char must_be_char) {
- corrupted_if(remain() < 1);
- corrupted_if(*_p++ != must_be_char);
+ corrupted_if(remain() < 1, "Truncated");
+ corrupted_if(*_p++ != must_be_char, "Unexpected character");
return 0;
}
void HashtableTextDump::skip_past(char c) {
for (;;) {
- corrupted_if(remain() < 1);
+ corrupted_if(remain() < 1, "Truncated");
if (*_p++ == c) {
return;
}
@@ -381,7 +381,7 @@
void HashtableTextDump::check_version(const char* ver) {
int len = (int)strlen(ver);
- corrupted_if(remain() < len);
+ corrupted_if(remain() < len, "Truncated");
if (strncmp(_p, ver, len) != 0) {
quit("wrong version of hashtable dump file", _filename);
}
@@ -451,7 +451,7 @@
jchar HashtableTextDump::unescape(const char* from, const char* end, int count) {
jchar value = 0;
- corrupted_if(from + count > end);
+ corrupted_if(from + count > end, "Truncated");
for (int i=0; i<count; i++) {
char c = *from++;
@@ -486,7 +486,7 @@
if (*from != '\\') {
*to++ = *from++;
} else {
- corrupted_if(from + 2 > end);
+ corrupted_if(from + 2 > end, "Truncated");
char c = from[1];
from += 2;
switch (c) {
@@ -507,7 +507,7 @@
}
}
}
- corrupted_if(n > 0); // expected more chars but file has ended
+ corrupted_if(n > 0, "Truncated"); // expected more chars but file has ended
_p = from;
skip_newline();
}
--- a/hotspot/src/share/vm/classfile/compactHashtable.hpp Thu Jan 28 02:30:57 2016 +0100
+++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp Wed Jan 27 22:39:03 2016 -0500
@@ -276,9 +276,9 @@
void corrupted(const char *p, const char *msg);
- inline void corrupted_if(bool cond) {
+ inline void corrupted_if(bool cond, const char *msg) {
if (cond) {
- corrupted(_p, NULL);
+ corrupted(_p, msg);
}
}
@@ -287,27 +287,30 @@
void skip_past(char c);
void check_version(const char* ver);
- inline bool get_num(char delim, int *utf8_length) {
+ inline void get_num(char delim, int *num) {
const char* p = _p;
const char* end = _end;
- int num = 0;
+ u8 n = 0;
while (p < end) {
char c = *p ++;
if ('0' <= c && c <= '9') {
- num = num * 10 + (c - '0');
+ n = n * 10 + (c - '0');
+ if (n > (u8)INT_MAX) {
+ corrupted(_p, "Num overflow");
+ }
} else if (c == delim) {
_p = p;
- *utf8_length = num;
- return true;
+ *num = (int)n;
+ return;
} else {
// Not [0-9], not 'delim'
- return false;
+ corrupted(_p, "Unrecognized format");;
}
}
+
corrupted(_end, "Incorrect format");
ShouldNotReachHere();
- return false;
}
void scan_prefix_type();