8336032: Enforce immutability of Lists used by ClassFile API
Reviewed-by: asotona
This commit is contained in:
parent
a91f9ba849
commit
6154a2129b
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -148,7 +148,7 @@ public final class BufferedCodeBuilder
|
||||
implements CodeModel {
|
||||
|
||||
private Model() {
|
||||
super(elements);
|
||||
super(BufferedCodeBuilder.this.elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,7 +78,7 @@ public final class BufferedFieldBuilder
|
||||
extends AbstractUnboundModel<FieldElement>
|
||||
implements FieldModel {
|
||||
public Model() {
|
||||
super(elements);
|
||||
super(BufferedFieldBuilder.this.elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,7 +156,7 @@ public final class BufferedMethodBuilder
|
||||
extends AbstractUnboundModel<MethodElement>
|
||||
implements MethodModel, MethodInfo {
|
||||
public Model() {
|
||||
super(elements);
|
||||
super(BufferedMethodBuilder.this.elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user