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
 23  * questions.
 24  */
 25 package jdk.internal.classfile.impl.verifier;
 26 
 27 import java.lang.classfile.constantpool.NameAndTypeEntry;
 28 import java.lang.classfile.constantpool.Utf8Entry;
 29 import java.util.Arrays;
 30 import java.util.Set;
 31 
 32 import jdk.internal.classfile.impl.TemporaryConstantPool;
 33 
 34 /// From `stackMapFrame.cpp`.
 35 class VerificationFrame {
 36 
 37     public static final int FLAG_THIS_UNINIT = 0x01;
 38 
 39     private int _offset;
 40     private int _locals_size, _stack_size;
 41     private int _stack_mark;
 42     private final int _max_locals, _max_stack;
 43     private int _flags;
 44     private final VerificationType[] _locals, _stack;
 45     private Set<NameAndTypeEntry> _assert_unset_fields;
 46     private final VerifierImpl _verifier;
 47 
 48     public VerificationFrame(int offset, int flags, int locals_size, int stack_size, int max_locals, int max_stack,
 49                              VerificationType[] locals, VerificationType[] stack, Set<NameAndTypeEntry> assert_unset_fields, VerifierImpl v) {
 50         this._offset = offset;
 51         this._locals_size = locals_size;
 52         this._stack_size = stack_size;
 53         this._stack_mark = -1;
 54         this._max_locals = max_locals;
 55         this._max_stack = max_stack;
 56         this._flags = flags;
 57         this._locals = locals;
 58         this._stack = stack;
 59         this._assert_unset_fields = assert_unset_fields;
 60         this._verifier = v;
 61     }
 62 
 63     @Override
 64     public String toString() {
 65         return "frame @" + _offset + " with locals " + (_locals == null ? "[]" : Arrays.asList(_locals)) + " and stack " + (_stack == null ? "[]" : Arrays.asList(_stack));
 66     }
 67 
 68     void set_offset(int offset) {
 69         this._offset = offset;
 70     }
 71 
 72     void set_flags(int flags) {
 73         _flags = flags;
 74     }
 75 
 76     void set_locals_size(int locals_size) {
 77         _locals_size = locals_size;
 78     }
 79 
 80     void set_stack_size(int stack_size) {
 81         _stack_size = _stack_mark = stack_size;
 82     }
 83 
 84     int offset() {
 85         return _offset;
 86     }
 87 
 88     VerifierImpl verifier() {
 89         return _verifier;
 90     }
 91 
 92     int flags() {
 93         return _flags;
 94     }
 95 
 96     int locals_size() {
 97         return _locals_size;
 98     }
 99 
100     VerificationType[] locals() {
101         return _locals;
102     }
103 
104     int stack_size() {
105         return _stack_size;
106     }
107 
108     VerificationType[] stack() {
109         return _stack;
110     }
111 
112     int max_locals() {
113         return _max_locals;
114     }
115 
116     boolean flag_this_uninit() {
117         return (_flags & FLAG_THIS_UNINIT) == FLAG_THIS_UNINIT;
118     }
119 
120     Set<NameAndTypeEntry> assert_unset_fields() {
121         return _assert_unset_fields;
122     }
123 
124     void set_assert_unset_fields(Set<NameAndTypeEntry> table) {
125         _assert_unset_fields = table;
126     }
127 
128     // Called when verifying putfields to mark strict instance fields as satisfied
129     boolean satisfy_unset_field(Utf8Entry name, Utf8Entry signature) {
130         var nat = TemporaryConstantPool.INSTANCE.nameAndTypeEntry(name, signature);
131         return _assert_unset_fields.remove(nat);
132     }
133 
134     // Verify that all strict fields have been initialized
135     // Strict fields must be initialized before the super constructor is called
136     boolean verify_unset_fields_satisfied() {
137         return _assert_unset_fields.isEmpty();
138     }
139 
140     // Merge incoming unset strict fields from StackMapTable with
141     // initial strict instance fields
142     Set<NameAndTypeEntry> merge_unset_fields(Set<NameAndTypeEntry> new_fields) {
143         // ClassFile API: We track all strict fields in another structure, noop here
144         return new_fields;
145     }
146 
147     boolean verify_unset_fields_compatibility(Set<NameAndTypeEntry> target_table) {
148         for (var e : _assert_unset_fields) {
149             if (!target_table.contains(e))
150                 return false;
151         }
152         return true;
153     }
154 
155     void unsatisfied_strict_fields_error(VerificationWrapper klass, int bci) {
156         _verifier.verifyError("All strict final fields must be initialized before super(): %d field(s), %s"
157                 .formatted(_assert_unset_fields.size(), _assert_unset_fields));
158     }
159 
160     void print_strict_fields(Set<NameAndTypeEntry> table) {
161         // ignore, we don't do stdout/err
162     }
163 
164     void reset() {
165         for (int i = 0; i < _max_locals; i++) {
166             _locals[i] = VerificationType.bogus_type;
167         }
168         for (int i = 0; i < _max_stack; i++) {
169             _stack[i] = VerificationType.bogus_type;
170         }
171     }
172 
173     void set_mark() {
174         if (_stack_mark != -1) {
175             for (int i = _stack_mark - 1; i >= _stack_size; --i) {
176                 _stack[i] = VerificationType.bogus_type;
177             }
178             _stack_mark = _stack_size;
179         }
180     }
181 
182     void push_stack(VerificationType type) {
183         if (type.is_check()) _verifier.verifyError("Must be a real type");
184         if (_stack_size >= _max_stack) {
185             _verifier.verifyError("Operand stack overflow");
186         }
187         _stack[_stack_size++] = type;
188     }
189 
190     void push_stack_2(VerificationType type1, VerificationType type2) {
191         if (!(type1.is_long() || type1.is_double())) _verifier.verifyError("must be long/double");
192         if (!(type2.is_long2() || type2.is_double2())) _verifier.verifyError("must be long/double_2");
193         if (_stack_size >= _max_stack - 1) {
194             _verifier.verifyError("Operand stack overflow");
195         }
196         _stack[_stack_size++] = type1;
197         _stack[_stack_size++] = type2;
198     }
199 
200     VerificationType pop_stack() {
201         if (_stack_size <= 0) {
202             _verifier.verifyError("Operand stack underflow");
203         }
204         return _stack[--_stack_size];
205     }
206 
207     VerificationType pop_stack(VerificationType type) {
208         if (_stack_size != 0) {
209             VerificationType top = _stack[_stack_size - 1];
210             boolean subtype = type.is_assignable_from(top, verifier());
211             if (subtype) {
212                 --_stack_size;
213                 return top;
214             }
215         }
216         return pop_stack_ex(type);
217     }
218 
219     void pop_stack_2(VerificationType type1, VerificationType type2) {
220         if (!(type1.is_long2() || type1.is_double2())) _verifier.verifyError("must be long/double");
221         if (!(type2.is_long() || type2.is_double())) _verifier.verifyError("must be long/double_2");
222         if (_stack_size >= 2) {
223             VerificationType top1 = _stack[_stack_size - 1];
224             boolean subtype1 = type1.is_assignable_from(top1, verifier());
225             VerificationType top2 = _stack[_stack_size - 2];
226             boolean subtype2 = type2.is_assignable_from(top2, verifier());
227             if (subtype1 && subtype2) {
228                 _stack_size -= 2;
229                 return;
230             }
231         }
232         pop_stack_ex(type1);
233         pop_stack_ex(type2);
234     }
235 
236     VerificationFrame(int max_locals, int max_stack, Set<NameAndTypeEntry> initial_strict_fields, VerifierImpl verifier) {
237         _offset = 0;
238         _locals_size = 0;
239         _stack_size = 0;
240         _stack_mark = 0;
241         _max_locals = max_locals;
242         _max_stack = max_stack;
243         _flags = 0;
244         _verifier = verifier;
245         _locals = new VerificationType[max_locals];
246         _stack = new VerificationType[max_stack];
247         for (int i = 0; i < max_locals; i++) {
248             _locals[i] = VerificationType.bogus_type;
249         }
250         for (int i = 0; i < max_stack; i++) {
251             _stack[i] = VerificationType.bogus_type;
252         }
253         _assert_unset_fields = initial_strict_fields;
254     }
255 
256     VerificationFrame frame_in_exception_handler(int flags) {
257         return new VerificationFrame(_offset, flags, _locals_size, 0,
258                 _max_locals, _max_stack, _locals, new VerificationType[1],
259                 _assert_unset_fields, _verifier);
260     }
261 
262     void initialize_object(VerificationType old_object, VerificationType new_object) {
263         int i;
264         for (i = 0; i < _max_locals; i++) {
265             if (_locals[i].equals(old_object)) {
266                 _locals[i] = new_object;
267             }
268         }
269         for (i = 0; i < _stack_size; i++) {
270             if (_stack[i].equals(old_object)) {
271                 _stack[i] = new_object;
272             }
273         }
274         if (old_object.is_uninitialized_this(_verifier)) {
275             _flags = 0;
276         }
277     }
278 
279     VerificationType  set_locals_from_arg(VerificationWrapper.MethodWrapper m, VerificationType thisKlass) {
280         var ss = new VerificationSignature(m.descriptor(), true, _verifier);
281         int init_local_num = 0;
282         if (!m.isStatic()) {
283             init_local_num++;
284             if (VerifierImpl.object_initializer_name.equals(m.name()) && !VerifierImpl.java_lang_Object.equals(thisKlass.name())) {
285                 _locals[0] = VerificationType.uninitialized_this_type;
286                 _flags |= FLAG_THIS_UNINIT;
287             } else {
288                 _locals[0] = thisKlass;
289             }
290         }
291         while (!ss.atReturnType()) {
292             init_local_num += _verifier.change_sig_to_verificationType(ss, _locals, init_local_num);
293             ss.next();
294         }
295         _locals_size = init_local_num;
296         switch (ss.type()) {
297             case T_OBJECT:
298             case T_ARRAY:
299             {
300                 String sig = ss.asSymbol();
301                 return VerificationType.reference_type(sig);
302             }
303             case T_INT:         return VerificationType.integer_type;
304             case T_BYTE:        return VerificationType.byte_type;
305             case T_CHAR:        return VerificationType.char_type;
306             case T_SHORT:     return VerificationType.short_type;
307             case T_BOOLEAN: return VerificationType.boolean_type;
308             case T_FLOAT:     return VerificationType.float_type;
309             case T_DOUBLE:    return VerificationType.double_type;
310             case T_LONG:        return VerificationType.long_type;
311             case T_VOID:        return VerificationType.bogus_type;
312             default:
313                 _verifier.verifyError("Should not reach here");
314                 return VerificationType.bogus_type;
315         }
316     }
317 
318     void copy_locals(VerificationFrame src) {
319         int len = src.locals_size() < _locals_size ? src.locals_size() : _locals_size;
320         if (len > 0) System.arraycopy(src.locals(), 0, _locals, 0, len);
321     }
322 
323     void copy_stack(VerificationFrame src) {
324         int len = src.stack_size() < _stack_size ? src.stack_size() : _stack_size;
325         if (len > 0) System.arraycopy(src.stack(), 0, _stack, 0, len);
326     }
327 
328     private int is_assignable_to(VerificationType[] from, VerificationType[] to, int len) {
329         int i = 0;
330         for (; i < len; i++) {
331             if (!to[i].is_assignable_from(from[i], verifier())) {
332                 break;
333             }
334         }
335         return i;
336     }
337 
338     boolean is_assignable_to(VerificationFrame target) {
339         if (_max_locals != target.max_locals()) {
340             _verifier.verifyError("Locals size mismatch", this, target);
341         }
342         if (_stack_size != target.stack_size()) {
343             _verifier.verifyError("Stack size mismatch", this, target);
344         }
345         int mismatch_loc;
346         mismatch_loc = is_assignable_to(_locals, target.locals(), target.locals_size());
347         if (mismatch_loc != target.locals_size()) {
348             _verifier.verifyError("Bad type", this, target);
349         }
350         mismatch_loc = is_assignable_to(_stack, target.stack(), _stack_size);
351         if (mismatch_loc != _stack_size) {
352             _verifier.verifyError("Bad type", this, target);
353         }
354 
355         // Check that assert unset fields are compatible
356         boolean compatible = verify_unset_fields_compatibility(target.assert_unset_fields());
357         if (!compatible) {
358             print_strict_fields(assert_unset_fields());
359             print_strict_fields(target.assert_unset_fields());
360             _verifier.verifyError("Strict fields mismatch from %s to %s".formatted(
361                     assert_unset_fields(), target.assert_unset_fields()), this, target);
362             return false;
363         }
364 
365         if ((_flags | target.flags()) == target.flags()) {
366             return true;
367         } else {
368             _verifier.verifyError("Bad flags", this, target);
369         }
370         return false;
371     }
372 
373     VerificationType pop_stack_ex(VerificationType type) {
374         if (_stack_size <= 0) {
375             _verifier.verifyError("Operand stack underflow");
376         }
377         VerificationType top = _stack[--_stack_size];
378         boolean subtype = type.is_assignable_from(top, verifier());
379         if (!subtype) {
380             _verifier.verifyError("Bad type on operand stack");
381         }
382         return top;
383     }
384 
385     VerificationType get_local(int index, VerificationType type) {
386         if (index >= _max_locals) {
387             _verifier.verifyError("Local variable table overflow");
388         }
389         boolean subtype = type.is_assignable_from(_locals[index],
390             verifier());
391         if (!subtype) {
392             _verifier.verifyError("Bad local variable type");
393         }
394         if(index >= _locals_size) { _locals_size = index + 1; }
395         return _locals[index];
396     }
397 
398     void get_local_2(int index, VerificationType type1, VerificationType type2) {
399         if (!(type1.is_long() || type1.is_double())) _verifier.verifyError("must be long/double");
400         if (!(type2.is_long2() || type2.is_double2())) _verifier.verifyError("must be long/double_2");
401         if (index >= _locals_size - 1) {
402             _verifier.verifyError("get long/double overflows locals");
403         }
404         boolean subtype = type1.is_assignable_from(_locals[index], verifier());
405         if (!subtype) {
406             _verifier.verifyError("Bad local variable type");
407         } else {
408             subtype = type2.is_assignable_from(_locals[index + 1], verifier());
409             if (!subtype) {
410                 _verifier.verifyError("Bad local variable type");
411             }
412         }
413     }
414 
415     void set_local(int index, VerificationType type) {
416         if (type.is_check()) _verifier.verifyError("Must be a real type");
417         if (index >= _max_locals) {
418             _verifier.verifyError("Local variable table overflow");
419         }
420         if (_locals[index].is_double() || _locals[index].is_long()) {
421             if ((index + 1) >= _locals_size) _verifier.verifyError("Local variable table overflow");
422             _locals[index + 1] = VerificationType.bogus_type;
423         }
424         if (_locals[index].is_double2() || _locals[index].is_long2()) {
425             if (index < 1) _verifier.verifyError("Local variable table underflow");
426             _locals[index - 1] = VerificationType.bogus_type;
427         }
428         _locals[index] = type;
429         if (index >= _locals_size) {
430             for (int i=_locals_size; i<index; i++) {
431                 if (_locals[i] != VerificationType.bogus_type) _verifier.verifyError("holes must be bogus type");
432             }
433             _locals_size = index + 1;
434         }
435     }
436 
437     void set_local_2(int index, VerificationType type1, VerificationType type2) {
438         if (!(type1.is_long() || type1.is_double())) _verifier.verifyError("must be long/double");
439         if (!(type2.is_long2() || type2.is_double2())) _verifier.verifyError("must be long/double_2");
440         if (index >= _max_locals - 1) {
441             _verifier.verifyError("Local variable table overflow");
442         }
443         if (_locals[index+1].is_double() || _locals[index+1].is_long()) {
444             if ((index + 2) >= _locals_size) _verifier.verifyError("Local variable table overflow");
445             _locals[index + 2] = VerificationType.bogus_type;
446         }
447         if (_locals[index].is_double2() || _locals[index].is_long2()) {
448             if (index < 1) _verifier.verifyError("Local variable table underflow");
449             _locals[index - 1] = VerificationType.bogus_type;
450         }
451         _locals[index] = type1;
452         _locals[index+1] = type2;
453         if (index >= _locals_size - 1) {
454             for (int i=_locals_size; i<index; i++) {
455                 if (_locals[i] != VerificationType.bogus_type) _verifier.verifyError("holes must be bogus type");
456             }
457             _locals_size = index + 2;
458         }
459     }
460 }