8336032: Enforce immutability of Lists used by ClassFile API

Reviewed-by: asotona
This commit is contained in:
Chen Liang 2024-07-30 17:41:38 +00:00
parent a91f9ba849
commit 6154a2129b
11 changed files with 29 additions and 13 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package java.lang.classfile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -83,6 +84,6 @@ public sealed interface AttributedElement extends ClassFileElement
list.add(t);
}
}
return list;
return Collections.unmodifiableList(list);
}
}

View File

@ -76,7 +76,7 @@ public sealed interface ClassSignature
Signature.ClassTypeSig superclassSignature,
Signature.ClassTypeSig... superinterfaceSignatures) {
return new SignaturesImpl.ClassSignatureImpl(
requireNonNull(typeParameters),
List.copyOf(requireNonNull(typeParameters)),
requireNonNull(superclassSignature),
List.of(superinterfaceSignatures));
}

View File

@ -25,6 +25,7 @@
package java.lang.classfile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
@ -90,7 +91,7 @@ public sealed interface CompoundElement<E extends ClassFileElement>
list.add(e);
}
});
return list;
return Collections.unmodifiableList(list);
}
}

View File

@ -24,6 +24,7 @@
*/
package jdk.internal.classfile.impl;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
@ -37,11 +38,11 @@ public abstract sealed class AbstractUnboundModel<E extends ClassFileElement>
extends AbstractElement
implements CompoundElement<E>, AttributedElement
permits BufferedCodeBuilder.Model, BufferedFieldBuilder.Model, BufferedMethodBuilder.Model {
private final List<E> elements;
final List<E> elements;
private List<Attribute<?>> attributes;
public AbstractUnboundModel(List<E> elements) {
this.elements = elements;
this.elements = Collections.unmodifiableList(elements);
}
@Override

View File

@ -39,6 +39,7 @@ import java.lang.classfile.constantpool.Utf8Entry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
@ -134,7 +135,6 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
var filled = new ArrayList<Attribute<?>>(size);
int p = pos + 2;
int cfLen = reader.classfileLength();
var apo = ((ClassReaderImpl)reader).context().attributesProcessingOption();
for (int i = 0; i < size; ++i) {
Utf8Entry name = reader.readEntry(p, Utf8Entry.class);
int len = reader.readInt(p + 2);
@ -148,7 +148,7 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
mapper = customAttributes.apply(name);
}
if (mapper != null) {
filled.add((Attribute)mapper.readAttribute(enclosing, reader, p));
filled.add((Attribute<?>) Objects.requireNonNull(mapper.readAttribute(enclosing, reader, p)));
} else {
AttributeMapper<UnknownAttribute> fakeMapper = new AttributeMapper<>() {
@Override

View File

@ -148,7 +148,7 @@ public final class BufferedCodeBuilder
implements CodeModel {
private Model() {
super(elements);
super(BufferedCodeBuilder.this.elements);
}
@Override

View File

@ -78,7 +78,7 @@ public final class BufferedFieldBuilder
extends AbstractUnboundModel<FieldElement>
implements FieldModel {
public Model() {
super(elements);
super(BufferedFieldBuilder.this.elements);
}
@Override

View File

@ -156,7 +156,7 @@ public final class BufferedMethodBuilder
extends AbstractUnboundModel<MethodElement>
implements MethodModel, MethodInfo {
public Model() {
super(elements);
super(BufferedMethodBuilder.this.elements);
}
@Override

View File

@ -285,5 +285,9 @@ public class StackMapDecoder {
List<VerificationTypeInfo> locals,
List<VerificationTypeInfo> stack)
implements StackMapFrameInfo {
public StackMapFrameImpl {
locals = List.copyOf(locals);
stack = List.copyOf(stack);
}
}
}

View File

@ -92,6 +92,8 @@ import java.lang.classfile.constantpool.NameAndTypeEntry;
import java.lang.classfile.constantpool.PackageEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.access.SharedSecrets;
public abstract sealed class UnboundAttribute<T extends Attribute<T>>
extends AbstractElement
implements Attribute<T>, Util.Writable {
@ -627,7 +629,13 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) {
super(Attributes.runtimeInvisibleParameterAnnotations());
this.elements = List.copyOf(elements);
// deep copy
var array = elements.toArray().clone();
for (int i = 0; i < array.length; i++) {
array[i] = List.copyOf((List<?>) array[i]);
}
this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array);
}
@Override

View File

@ -26,6 +26,7 @@ package jdk.internal.classfile.impl.verifier;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.lang.classfile.ClassHierarchyResolver;
@ -133,7 +134,7 @@ public final class VerifierImpl {
errors.addAll(inference_verify(klass));
}
}
return errors;
return Collections.unmodifiableList(errors);
} finally {
log_info(logger, "End class verification for: %s", clsName);
}