@@ -132,9 +132,19 @@ class java_bytecode_parsert final : public parsert
132
132
T read ()
133
133
{
134
134
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" );
136
137
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 ;
138
148
for (size_t i = 0 ; i < bytes; i++)
139
149
{
140
150
if (!*in)
@@ -145,7 +155,7 @@ class java_bytecode_parsert final : public parsert
145
155
result <<= 8u ;
146
156
result |= static_cast <u1>(in->get ());
147
157
}
148
- return narrow_cast<T>( result) ;
158
+ return result;
149
159
}
150
160
151
161
void store_unknown_method_handle (size_t bootstrap_method_index);
@@ -695,15 +705,15 @@ void java_bytecode_parsert::rconstant_pool()
695
705
break ;
696
706
697
707
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
706
715
break ;
716
+ }
707
717
708
718
case CONSTANT_MethodHandle:
709
719
it->ref1 = read<u1>();
@@ -941,34 +951,34 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
941
951
break ;
942
952
943
953
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 )));
948
957
address+=1 ;
949
958
break ;
959
+ }
950
960
951
961
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 )));
959
968
address+=2 ;
960
969
break ;
970
+ }
961
971
962
972
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 )));
970
979
address+=4 ;
971
980
break ;
981
+ }
972
982
973
983
case ' v' : // local variable index (one byte)
974
984
{
@@ -994,15 +1004,15 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
994
1004
{
995
1005
const u2 v = read<u2>();
996
1006
instruction.args .push_back (from_integer (v, unsignedbv_typet (16 )));
997
- const s2 c = read<u2 >();
1007
+ const s2 c = read<s2 >();
998
1008
instruction.args .push_back (from_integer (c, signedbv_typet (16 )));
999
1009
address+=4 ;
1000
1010
}
1001
1011
else // local variable index (one byte) plus one signed byte
1002
1012
{
1003
1013
const u1 v = read<u1>();
1004
1014
instruction.args .push_back (from_integer (v, unsignedbv_typet (8 )));
1005
- const s1 c = read<u1 >();
1015
+ const s1 c = read<s1 >();
1006
1016
instruction.args .push_back (from_integer (c, signedbv_typet (8 )));
1007
1017
address+=2 ;
1008
1018
}
@@ -1032,7 +1042,7 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
1032
1042
}
1033
1043
1034
1044
// now default value
1035
- const s4 default_value = read<u4 >();
1045
+ const s4 default_value = read<s4 >();
1036
1046
// By converting the signed offset into an absolute address (by adding
1037
1047
// the current address) the number represented becomes unsigned.
1038
1048
instruction.args .push_back (
@@ -1045,8 +1055,8 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
1045
1055
1046
1056
for (std::size_t i=0 ; i<npairs; i++)
1047
1057
{
1048
- const s4 match = read<u4 >();
1049
- const s4 offset = read<u4 >();
1058
+ const s4 match = read<s4 >();
1059
+ const s4 offset = read<s4 >();
1050
1060
instruction.args .push_back (
1051
1061
from_integer (match, signedbv_typet (32 )));
1052
1062
// By converting the signed offset into an absolute address (by adding
@@ -1070,23 +1080,23 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
1070
1080
}
1071
1081
1072
1082
// now default value
1073
- const s4 default_value = read<u4 >();
1083
+ const s4 default_value = read<s4 >();
1074
1084
instruction.args .push_back (
1075
1085
from_integer (base_offset+default_value, signedbv_typet (32 )));
1076
1086
address+=4 ;
1077
1087
1078
1088
// now low value
1079
- const s4 low_value = read<u4 >();
1089
+ const s4 low_value = read<s4 >();
1080
1090
address+=4 ;
1081
1091
1082
1092
// now high value
1083
- const s4 high_value = read<u4 >();
1093
+ const s4 high_value = read<s4 >();
1084
1094
address+=4 ;
1085
1095
1086
1096
// there are high-low+1 offsets, and they are signed
1087
1097
for (s4 i=low_value; i<=high_value; i++)
1088
1098
{
1089
- s4 offset = read<u4 >();
1099
+ s4 offset = read<s4 >();
1090
1100
instruction.args .push_back (from_integer (i, signedbv_typet (32 )));
1091
1101
// By converting the signed offset into an absolute address (by adding
1092
1102
// the current address) the number represented becomes unsigned.
@@ -1130,8 +1140,8 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
1130
1140
1131
1141
case ' s' : // a signed short
1132
1142
{
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 )));
1135
1145
}
1136
1146
address+=2 ;
1137
1147
break ;
0 commit comments