24 */
25 package jdk.internal.classfile.impl.verifier;
26
27 import java.lang.classfile.*;
28 import java.lang.classfile.attribute.*;
29 import java.lang.classfile.constantpool.*;
30 import java.lang.constant.ClassDesc;
31 import java.lang.constant.ConstantDescs;
32 import java.lang.reflect.AccessFlag;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.stream.Collectors;
38 import java.util.function.Function;
39 import java.util.function.ToIntFunction;
40
41 import jdk.internal.classfile.impl.BoundAttribute;
42 import jdk.internal.classfile.impl.Util;
43
44 import static java.lang.constant.ConstantDescs.CLASS_INIT_NAME;
45 import static java.lang.constant.ConstantDescs.INIT_NAME;
46 import static jdk.internal.classfile.impl.StackMapGenerator.*;
47
48 /// ParserVerifier performs selected checks of the class file format according to
49 /// {@jvms 4.8 Format Checking}.
50 ///
51 /// From `classFileParser.cpp`.
52 ///
53 public record ParserVerifier(ClassModel classModel) {
54
55 List<VerifyError> verify() {
56 var errors = new ArrayList<VerifyError>();
57 verifyConstantPool(errors);
58 verifyInterfaces(errors);
59 verifyFields(errors);
60 verifyMethods(errors);
61 verifyAttributes(classModel, errors);
62 return errors;
63 }
64
65 private void verifyConstantPool(List<VerifyError> errors) {
260 }
261 case DeprecatedAttribute _ ->
262 0;
263 case EnclosingMethodAttribute ema -> {
264 ema.enclosingClass();
265 ema.enclosingMethod();
266 yield 4;
267 }
268 case ExceptionsAttribute ea ->
269 2 + 2 * ea.exceptions().size();
270 case InnerClassesAttribute ica -> {
271 for (var ici : ica.classes()) {
272 if (ici.outerClass().isPresent() && ici.outerClass().get().equals(ici.innerClass())) {
273 errors.add(new VerifyError("Class is both outer and inner class in %s".formatted(toString(ae))));
274 }
275 }
276 yield 2 + 8 * ica.classes().size();
277 }
278 case LineNumberTableAttribute lta ->
279 2 + 4 * lta.lineNumbers().size();
280 case LocalVariableTableAttribute lvta ->
281 2 + 10 * lvta.localVariables().size();
282 case LocalVariableTypeTableAttribute lvta ->
283 2 + 10 * lvta.localVariableTypes().size();
284 case MethodParametersAttribute mpa ->
285 1 + 4 * mpa.parameters().size();
286 case ModuleAttribute ma ->
287 16 + subSize(ma.exports(), ModuleExportInfo::exportsTo, 6, 2)
288 + subSize(ma.opens(), ModuleOpenInfo::opensTo, 6, 2)
289 + subSize(ma.provides(), ModuleProvideInfo::providesWith, 4, 2)
290 + 6 * ma.requires().size()
291 + 2 * ma.uses().size();
292 case ModuleHashesAttribute mha ->
293 2 + moduleHashesSize(mha.hashes());
294 case ModuleMainClassAttribute mmca -> {
295 mmca.mainClass();
296 yield 2;
297 }
298 case ModulePackagesAttribute mpa ->
299 2 + 2 * mpa.packages().size();
330 case RuntimeInvisibleTypeAnnotationsAttribute aa ->
331 typeAnnotationsSize(aa.annotations());
332 case RuntimeVisibleParameterAnnotationsAttribute aa ->
333 parameterAnnotationsSize(aa.parameterAnnotations());
334 case RuntimeInvisibleParameterAnnotationsAttribute aa ->
335 parameterAnnotationsSize(aa.parameterAnnotations());
336 case SignatureAttribute sa -> {
337 sa.signature();
338 yield 2;
339 }
340 case SourceDebugExtensionAttribute sda ->
341 sda.contents().length;
342 case SourceFileAttribute sfa -> {
343 sfa.sourceFile();
344 yield 2;
345 }
346 case SourceIDAttribute sida -> {
347 sida.sourceId();
348 yield 2;
349 }
350 case StackMapTableAttribute smta ->
351 2 + subSize(smta.entries(), frame -> stackMapFrameSize(frame));
352 case SyntheticAttribute _ ->
353 0;
354 case UnknownAttribute _ ->
355 -1;
356 case CustomAttribute<?> _ ->
357 -1;
358 default -> // should not happen if all known attributes are verified
359 throw new AssertionError(a);
360 };
361 if (size >= 0 && size != ((BoundAttribute)a).payloadLen()) {
362 errors.add(new VerifyError("Wrong %s attribute length in %s".formatted(a.attributeName().stringValue(), toString(ae))));
363 }
364 }
365
366 private static <T, S extends Collection<?>> int subSize(Collection<T> entries, Function<T, S> subMH, int entrySize, int subSize) {
367 return subSize(entries, (ToIntFunction<T>) t -> entrySize + subSize * subMH.apply(t).size());
368 }
369
370 private static <T> int subSize(Collection<T> entries, ToIntFunction<T> subMH) {
371 int l = 0;
|
24 */
25 package jdk.internal.classfile.impl.verifier;
26
27 import java.lang.classfile.*;
28 import java.lang.classfile.attribute.*;
29 import java.lang.classfile.constantpool.*;
30 import java.lang.constant.ClassDesc;
31 import java.lang.constant.ConstantDescs;
32 import java.lang.reflect.AccessFlag;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.stream.Collectors;
38 import java.util.function.Function;
39 import java.util.function.ToIntFunction;
40
41 import jdk.internal.classfile.impl.BoundAttribute;
42 import jdk.internal.classfile.impl.Util;
43
44 import static java.lang.constant.ConstantDescs.*;
45 import static jdk.internal.classfile.impl.StackMapGenerator.*;
46
47 /// ParserVerifier performs selected checks of the class file format according to
48 /// {@jvms 4.8 Format Checking}.
49 ///
50 /// From `classFileParser.cpp`.
51 ///
52 public record ParserVerifier(ClassModel classModel) {
53
54 List<VerifyError> verify() {
55 var errors = new ArrayList<VerifyError>();
56 verifyConstantPool(errors);
57 verifyInterfaces(errors);
58 verifyFields(errors);
59 verifyMethods(errors);
60 verifyAttributes(classModel, errors);
61 return errors;
62 }
63
64 private void verifyConstantPool(List<VerifyError> errors) {
259 }
260 case DeprecatedAttribute _ ->
261 0;
262 case EnclosingMethodAttribute ema -> {
263 ema.enclosingClass();
264 ema.enclosingMethod();
265 yield 4;
266 }
267 case ExceptionsAttribute ea ->
268 2 + 2 * ea.exceptions().size();
269 case InnerClassesAttribute ica -> {
270 for (var ici : ica.classes()) {
271 if (ici.outerClass().isPresent() && ici.outerClass().get().equals(ici.innerClass())) {
272 errors.add(new VerifyError("Class is both outer and inner class in %s".formatted(toString(ae))));
273 }
274 }
275 yield 2 + 8 * ica.classes().size();
276 }
277 case LineNumberTableAttribute lta ->
278 2 + 4 * lta.lineNumbers().size();
279 case LoadableDescriptorsAttribute lda -> {
280 for (var desc : lda.loadableDescriptorSymbols()) {
281 if (desc.equals(CD_void)) {
282 errors.add(new VerifyError("illegal signature %s".formatted(desc)));
283 }
284 }
285 yield 2 + 2 * lda.loadableDescriptors().size();
286 }
287 case LocalVariableTableAttribute lvta ->
288 2 + 10 * lvta.localVariables().size();
289 case LocalVariableTypeTableAttribute lvta ->
290 2 + 10 * lvta.localVariableTypes().size();
291 case MethodParametersAttribute mpa ->
292 1 + 4 * mpa.parameters().size();
293 case ModuleAttribute ma ->
294 16 + subSize(ma.exports(), ModuleExportInfo::exportsTo, 6, 2)
295 + subSize(ma.opens(), ModuleOpenInfo::opensTo, 6, 2)
296 + subSize(ma.provides(), ModuleProvideInfo::providesWith, 4, 2)
297 + 6 * ma.requires().size()
298 + 2 * ma.uses().size();
299 case ModuleHashesAttribute mha ->
300 2 + moduleHashesSize(mha.hashes());
301 case ModuleMainClassAttribute mmca -> {
302 mmca.mainClass();
303 yield 2;
304 }
305 case ModulePackagesAttribute mpa ->
306 2 + 2 * mpa.packages().size();
337 case RuntimeInvisibleTypeAnnotationsAttribute aa ->
338 typeAnnotationsSize(aa.annotations());
339 case RuntimeVisibleParameterAnnotationsAttribute aa ->
340 parameterAnnotationsSize(aa.parameterAnnotations());
341 case RuntimeInvisibleParameterAnnotationsAttribute aa ->
342 parameterAnnotationsSize(aa.parameterAnnotations());
343 case SignatureAttribute sa -> {
344 sa.signature();
345 yield 2;
346 }
347 case SourceDebugExtensionAttribute sda ->
348 sda.contents().length;
349 case SourceFileAttribute sfa -> {
350 sfa.sourceFile();
351 yield 2;
352 }
353 case SourceIDAttribute sida -> {
354 sida.sourceId();
355 yield 2;
356 }
357 case StackMapTableAttribute _ ->
358 -1; // Not sufficient info for assert unset size
359 case SyntheticAttribute _ ->
360 0;
361 case UnknownAttribute _ ->
362 -1;
363 case CustomAttribute<?> _ ->
364 -1;
365 default -> // should not happen if all known attributes are verified
366 throw new AssertionError(a);
367 };
368 if (size >= 0 && size != ((BoundAttribute)a).payloadLen()) {
369 errors.add(new VerifyError("Wrong %s attribute length in %s".formatted(a.attributeName().stringValue(), toString(ae))));
370 }
371 }
372
373 private static <T, S extends Collection<?>> int subSize(Collection<T> entries, Function<T, S> subMH, int entrySize, int subSize) {
374 return subSize(entries, (ToIntFunction<T>) t -> entrySize + subSize * subMH.apply(t).size());
375 }
376
377 private static <T> int subSize(Collection<T> entries, ToIntFunction<T> subMH) {
378 int l = 0;
|