1 /*
2 * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
142 if (!match || (target < 0 || target >= _code_length)) {
143 _verifier.verifyError(String.format("Inconsistent stackmap frames at branch target %d", target));
144 }
145 }
146
147 static class StackMapReader {
148
149 private final VerificationWrapper.ConstantPoolWrapper _cp;
150 private final StackMapStream _stream;
151 private final byte[] _code_data;
152 private final int _code_length;
153 private final int _frame_count;
154
155 void check_verification_type_array_size(int size, int max_size) {
156 if (size < 0 || size > max_size) {
157 _verifier.classError("StackMapTable format error: bad type array size");
158 }
159 }
160
161 private static final int
162 SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,
163 SAME_EXTENDED = 251,
164 FULL = 255;
165
166 public int get_frame_count() {
167 return _frame_count;
168 }
169
170 public void check_end() {
171 if (!_stream.at_end()) {
172 _verifier.classError("wrong attribute size");
173 }
174 }
175
176 private final VerifierImpl _verifier;
177
178 public StackMapReader(byte[] stackmapData, byte[] code_data, int code_len, VerificationWrapper.ConstantPoolWrapper cp, VerifierImpl context) {
179 this._verifier = context;
180 _stream = new StackMapStream(stackmapData, _verifier);
181 if (stackmapData != null) {
182 _frame_count = _stream.get_u2();
183 } else {
184 _frame_count = 0;
261 }
262 } else {
263 offset = pre_frame.offset() + frame_type - 63;
264 locals = pre_frame.locals();
265 }
266 VerificationType[] stack = new VerificationType[2];
267 int stack_size = 1;
268 stack[0] = parse_verification_type(null);
269 if (stack[0].is_category2()) {
270 stack[1] = stack[0].to_category2_2nd(_verifier);
271 stack_size = 2;
272 }
273 check_verification_type_array_size(stack_size, max_stack);
274 frame = new VerificationFrame(offset, pre_frame.flags(), pre_frame.locals_size(), stack_size, max_locals, max_stack, locals, stack, _verifier);
275 if (first && locals != null) {
276 frame.copy_locals(pre_frame);
277 }
278 return frame;
279 }
280 int offset_delta = _stream.get_u2();
281 if (frame_type < SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
282 _verifier.classError("reserved frame type");
283 }
284 if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
285 if (first) {
286 offset = offset_delta;
287 if (pre_frame.locals_size() > 0) {
288 locals = new VerificationType[pre_frame.locals_size()];
289 }
290 } else {
291 offset = pre_frame.offset() + offset_delta + 1;
292 locals = pre_frame.locals();
293 }
294 VerificationType[] stack = new VerificationType[2];
295 int stack_size = 1;
296 stack[0] = parse_verification_type(null);
297 if (stack[0].is_category2()) {
298 stack[1] = stack[0].to_category2_2nd(_verifier);
299 stack_size = 2;
300 }
301 check_verification_type_array_size(stack_size, max_stack);
|
1 /*
2 * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
142 if (!match || (target < 0 || target >= _code_length)) {
143 _verifier.verifyError(String.format("Inconsistent stackmap frames at branch target %d", target));
144 }
145 }
146
147 static class StackMapReader {
148
149 private final VerificationWrapper.ConstantPoolWrapper _cp;
150 private final StackMapStream _stream;
151 private final byte[] _code_data;
152 private final int _code_length;
153 private final int _frame_count;
154
155 void check_verification_type_array_size(int size, int max_size) {
156 if (size < 0 || size > max_size) {
157 _verifier.classError("StackMapTable format error: bad type array size");
158 }
159 }
160
161 private static final int
162 ASSERT_UNSET_FIELDS = 246,
163 SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,
164 SAME_EXTENDED = 251,
165 FULL = 255;
166 private static final int RESERVED_TAGS_UPPER_LIMIT = ASSERT_UNSET_FIELDS; // not inclusive
167
168 public int get_frame_count() {
169 return _frame_count;
170 }
171
172 public void check_end() {
173 if (!_stream.at_end()) {
174 _verifier.classError("wrong attribute size");
175 }
176 }
177
178 private final VerifierImpl _verifier;
179
180 public StackMapReader(byte[] stackmapData, byte[] code_data, int code_len, VerificationWrapper.ConstantPoolWrapper cp, VerifierImpl context) {
181 this._verifier = context;
182 _stream = new StackMapStream(stackmapData, _verifier);
183 if (stackmapData != null) {
184 _frame_count = _stream.get_u2();
185 } else {
186 _frame_count = 0;
263 }
264 } else {
265 offset = pre_frame.offset() + frame_type - 63;
266 locals = pre_frame.locals();
267 }
268 VerificationType[] stack = new VerificationType[2];
269 int stack_size = 1;
270 stack[0] = parse_verification_type(null);
271 if (stack[0].is_category2()) {
272 stack[1] = stack[0].to_category2_2nd(_verifier);
273 stack_size = 2;
274 }
275 check_verification_type_array_size(stack_size, max_stack);
276 frame = new VerificationFrame(offset, pre_frame.flags(), pre_frame.locals_size(), stack_size, max_locals, max_stack, locals, stack, _verifier);
277 if (first && locals != null) {
278 frame.copy_locals(pre_frame);
279 }
280 return frame;
281 }
282 int offset_delta = _stream.get_u2();
283 if (frame_type < RESERVED_TAGS_UPPER_LIMIT) {
284 _verifier.classError("reserved frame type");
285 }
286 if (frame_type == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
287 if (first) {
288 offset = offset_delta;
289 if (pre_frame.locals_size() > 0) {
290 locals = new VerificationType[pre_frame.locals_size()];
291 }
292 } else {
293 offset = pre_frame.offset() + offset_delta + 1;
294 locals = pre_frame.locals();
295 }
296 VerificationType[] stack = new VerificationType[2];
297 int stack_size = 1;
298 stack[0] = parse_verification_type(null);
299 if (stack[0].is_category2()) {
300 stack[1] = stack[0].to_category2_2nd(_verifier);
301 stack_size = 2;
302 }
303 check_verification_type_array_size(stack_size, max_stack);
|