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