Skip to content

Commit b25b55b

Browse files
committed
feat(protosreader): ✨ improve DEX opcode parsing and validation
Add support for const-string/jumbo opcode and enhance array opcodes to validate string array types. Improve error handling for unexpected types and missing register values. Register array now matches method register count.
1 parent fd58786 commit b25b55b

1 file changed

Lines changed: 29 additions & 6 deletions

File tree

src/EcoFlow.Exporter.Protos/ProtosReader.cs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ public static IEnumerable<Item> Enumerate(DexFile dex)
115115
if (methodIdRow.name_idx.data is not "<clinit>")
116116
continue;
117117

118-
var instructions = encodedMethodRow.code_off.insns;
119-
var registers = new string[byte.MaxValue];
118+
var code = encodedMethodRow.code_off;
119+
var instructions = code.insns;
120+
var registers = new string[code.registers_size];
120121

121122
for (int index = 0; index < instructions.Length; index++)
122123
{
@@ -133,12 +134,31 @@ public static IEnumerable<Item> Enumerate(DexFile dex)
133134

134135
registers[register] = stringValue.data;
135136
break;
137+
138+
case 0x1B: // const-string/jumbo
139+
var jumboRegister = (byte)(instruction >> 8);
140+
141+
var jumboStringIndexLow = (uint)instructions[++index];
142+
var jumboStringIndexHigh = (uint)instructions[++index];
143+
var jumboStringIndex = jumboStringIndexLow | (jumboStringIndexHigh << 16);
144+
145+
var jumboStringValue = dex.STRING_DATA_ITEM[jumboStringIndex];
146+
147+
registers[jumboRegister] = jumboStringValue.data;
148+
break;
149+
136150
case 0x24: // filled-new-array
151+
137152
var format = (byte)(instruction >> 8);
138153
var registerCount = (format & 0xF0) >> 4;
139154
var fifthRegisterIndex = format & 0x0F;
140155

141156
var typeIndex = instructions[++index];
157+
var typeDescriptor = dex.TYPE_ID_ITEM[typeIndex].TypeDescriptor;
158+
159+
if (typeDescriptor != "[Ljava/lang/String;")
160+
throw new InvalidOperationException($"Unexpected type descriptor: {typeDescriptor}");
161+
142162
var argumentRegistersEncoded = instructions[++index];
143163

144164
var firstRegisterIndex = argumentRegistersEncoded & 0x0F;
@@ -163,10 +183,8 @@ public static IEnumerable<Item> Enumerate(DexFile dex)
163183

164184
if (currentRegisterIndex < registers.Length)
165185
{
166-
var registerContent = registers[currentRegisterIndex];
167-
168-
if (registerContent is null)
169-
continue;
186+
if (registers[currentRegisterIndex] is not { } registerContent)
187+
throw new InvalidOperationException($"Register {currentRegisterIndex} does not contain a string part.");
170188

171189
stringBuilder.Append(registerContent);
172190
}
@@ -181,6 +199,11 @@ public static IEnumerable<Item> Enumerate(DexFile dex)
181199
var rangeRegisterCount = (byte)(instruction >> 8);
182200

183201
var rangeTypeIndex = instructions[++index];
202+
var rangeTypeDescriptor = dex.TYPE_ID_ITEM[rangeTypeIndex].TypeDescriptor;
203+
204+
if (rangeTypeDescriptor != "[Ljava/lang/String;")
205+
throw new InvalidOperationException($"Unexpected type descriptor: {rangeTypeDescriptor}");
206+
184207
var startRegisterIndex = instructions[++index];
185208

186209
var rangeStringBuilder = new StringBuilder();

0 commit comments

Comments
 (0)