Skip to content

Commit 8e49f91

Browse files
authored
Merge pull request #8584 from tautschnig/signed-read
Cleanup type conversions in java_bytecode_parsert::read
2 parents c9653bd + d0e1b69 commit 8e49f91

File tree

1 file changed

+50
-40
lines changed

1 file changed

+50
-40
lines changed

jbmc/src/java_bytecode/java_bytecode_parser.cpp

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,19 @@ class java_bytecode_parsert final : public parsert
132132
T read()
133133
{
134134
static_assert(
135-
std::is_unsigned<T>::value, "T should be an unsigned integer");
135+
std::is_unsigned<T>::value || std::is_signed<T>::value,
136+
"T should be a signed or unsigned integer");
136137
const constexpr size_t bytes = sizeof(T);
137-
u8 result = 0;
138+
if(bytes == 1)
139+
{
140+
if(!*in)
141+
{
142+
log.error() << "unexpected end of bytecode file" << messaget::eom;
143+
throw 0;
144+
}
145+
return static_cast<T>(in->get());
146+
}
147+
T result = 0;
138148
for(size_t i = 0; i < bytes; i++)
139149
{
140150
if(!*in)
@@ -145,7 +155,7 @@ class java_bytecode_parsert final : public parsert
145155
result <<= 8u;
146156
result |= static_cast<u1>(in->get());
147157
}
148-
return narrow_cast<T>(result);
158+
return result;
149159
}
150160

151161
void store_unknown_method_handle(size_t bootstrap_method_index);
@@ -695,15 +705,15 @@ void java_bytecode_parsert::rconstant_pool()
695705
break;
696706

697707
case CONSTANT_Utf8:
698-
{
699-
const u2 bytes = read<u2>();
700-
std::string s;
701-
s.resize(bytes);
702-
for(auto &ch : s)
703-
ch = read<u1>();
704-
it->s = s; // Add to string table
705-
}
708+
{
709+
const u2 bytes = read<u2>();
710+
std::string s;
711+
s.resize(bytes);
712+
for(auto &ch : s)
713+
ch = read<std::string::value_type>();
714+
it->s = s; // Add to string table
706715
break;
716+
}
707717

708718
case CONSTANT_MethodHandle:
709719
it->ref1 = read<u1>();
@@ -941,34 +951,34 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
941951
break;
942952

943953
case 'b': // a signed byte
944-
{
945-
const s1 c = read<u1>();
946-
instruction.args.push_back(from_integer(c, signedbv_typet(8)));
947-
}
954+
{
955+
const s1 c = read<s1>();
956+
instruction.args.push_back(from_integer(c, signedbv_typet(8)));
948957
address+=1;
949958
break;
959+
}
950960

951961
case 'o': // two byte branch offset, signed
952-
{
953-
const s2 offset = read<u2>();
954-
// By converting the signed offset into an absolute address (by adding
955-
// the current address) the number represented becomes unsigned.
956-
instruction.args.push_back(
957-
from_integer(address+offset, unsignedbv_typet(16)));
958-
}
962+
{
963+
const s2 offset = read<s2>();
964+
// By converting the signed offset into an absolute address (by adding
965+
// the current address) the number represented becomes unsigned.
966+
instruction.args.push_back(
967+
from_integer(address + offset, unsignedbv_typet(16)));
959968
address+=2;
960969
break;
970+
}
961971

962972
case 'O': // four byte branch offset, signed
963-
{
964-
const s4 offset = read<u4>();
965-
// By converting the signed offset into an absolute address (by adding
966-
// the current address) the number represented becomes unsigned.
967-
instruction.args.push_back(
968-
from_integer(address+offset, unsignedbv_typet(32)));
969-
}
973+
{
974+
const s4 offset = read<s4>();
975+
// By converting the signed offset into an absolute address (by adding
976+
// the current address) the number represented becomes unsigned.
977+
instruction.args.push_back(
978+
from_integer(address + offset, unsignedbv_typet(32)));
970979
address+=4;
971980
break;
981+
}
972982

973983
case 'v': // local variable index (one byte)
974984
{
@@ -994,15 +1004,15 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
9941004
{
9951005
const u2 v = read<u2>();
9961006
instruction.args.push_back(from_integer(v, unsignedbv_typet(16)));
997-
const s2 c = read<u2>();
1007+
const s2 c = read<s2>();
9981008
instruction.args.push_back(from_integer(c, signedbv_typet(16)));
9991009
address+=4;
10001010
}
10011011
else // local variable index (one byte) plus one signed byte
10021012
{
10031013
const u1 v = read<u1>();
10041014
instruction.args.push_back(from_integer(v, unsignedbv_typet(8)));
1005-
const s1 c = read<u1>();
1015+
const s1 c = read<s1>();
10061016
instruction.args.push_back(from_integer(c, signedbv_typet(8)));
10071017
address+=2;
10081018
}
@@ -1032,7 +1042,7 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
10321042
}
10331043

10341044
// now default value
1035-
const s4 default_value = read<u4>();
1045+
const s4 default_value = read<s4>();
10361046
// By converting the signed offset into an absolute address (by adding
10371047
// the current address) the number represented becomes unsigned.
10381048
instruction.args.push_back(
@@ -1045,8 +1055,8 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
10451055

10461056
for(std::size_t i=0; i<npairs; i++)
10471057
{
1048-
const s4 match = read<u4>();
1049-
const s4 offset = read<u4>();
1058+
const s4 match = read<s4>();
1059+
const s4 offset = read<s4>();
10501060
instruction.args.push_back(
10511061
from_integer(match, signedbv_typet(32)));
10521062
// By converting the signed offset into an absolute address (by adding
@@ -1070,23 +1080,23 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
10701080
}
10711081

10721082
// now default value
1073-
const s4 default_value = read<u4>();
1083+
const s4 default_value = read<s4>();
10741084
instruction.args.push_back(
10751085
from_integer(base_offset+default_value, signedbv_typet(32)));
10761086
address+=4;
10771087

10781088
// now low value
1079-
const s4 low_value = read<u4>();
1089+
const s4 low_value = read<s4>();
10801090
address+=4;
10811091

10821092
// now high value
1083-
const s4 high_value = read<u4>();
1093+
const s4 high_value = read<s4>();
10841094
address+=4;
10851095

10861096
// there are high-low+1 offsets, and they are signed
10871097
for(s4 i=low_value; i<=high_value; i++)
10881098
{
1089-
s4 offset = read<u4>();
1099+
s4 offset = read<s4>();
10901100
instruction.args.push_back(from_integer(i, signedbv_typet(32)));
10911101
// By converting the signed offset into an absolute address (by adding
10921102
// the current address) the number represented becomes unsigned.
@@ -1130,8 +1140,8 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
11301140

11311141
case 's': // a signed short
11321142
{
1133-
const s2 s = read<u2>();
1134-
instruction.args.push_back(from_integer(s, signedbv_typet(16)));
1143+
const s2 s = read<s2>();
1144+
instruction.args.push_back(from_integer(s, signedbv_typet(16)));
11351145
}
11361146
address+=2;
11371147
break;

0 commit comments

Comments
 (0)