Skip to content
Permalink
Browse files

6708: Add santiy check when allocating Object arrays in parser

Reviewed-by: hirt
  • Loading branch information
Henrik Dafgård committed Feb 26, 2020
1 parent c752ec1 commit 2352cecbc1e1d9fa2f9a43c782213c153c885b1e
@@ -44,15 +44,20 @@
final class ArrayReader implements IValueReader {

private final IValueReader reader;
private final ChunkStructure header;

ArrayReader(IValueReader reader) {
ArrayReader(IValueReader reader, ChunkStructure header) {
this.reader = reader;
this.header = header;
}

@Override
public Object readValue(byte[] bytes, Offset offset, long timestamp) throws InvalidJfrFileException {
int arraySize = readArraySize(bytes, offset.get());
offset.increase(DataType.INTEGER.getSize());
if (arraySize > header.getChunkSize()) {
throw new InvalidJfrFileException("Found array larger than chunk size"); //$NON-NLS-1$
}
Object[] array = new Object[arraySize];
for (int n = 0; n < arraySize; n++) {
array[n] = reader.readValue(bytes, offset, timestamp);
@@ -59,7 +59,7 @@ private ChunkLoaderV0(ChunkStructure structure, byte[] data, LoaderContext conte
@Override
public byte[] call() throws Exception {
// Read constants
ReaderFactory readerFactory = new ReaderFactory(metadata, data, context);
ReaderFactory readerFactory = new ReaderFactory(metadata, data, context, structure);

// Read events
EventParserManager eventParser = new EventParserManager(readerFactory, context, metadata.getProducers());
@@ -55,9 +55,12 @@
private final FastAccessNumberMap<ConstantMap> constants = new FastAccessNumberMap<>(100, 5);
private final ChunkMetadata metadata;
private final FastAccessNumberMap<LabeledIdentifier> types = new FastAccessNumberMap<>();
private final ChunkStructure header;

ReaderFactory(ChunkMetadata metadata, byte[] chunkData, LoaderContext context) throws InvalidJfrFileException {
ReaderFactory(ChunkMetadata metadata, byte[] chunkData, LoaderContext context, ChunkStructure header)
throws InvalidJfrFileException {
this.metadata = metadata;
this.header = header;
for (ProducerDescriptor pd : metadata.getProducers()) {
for (ContentTypeDescriptor ct : pd.getContentTypes()) {
IValueReader reader = createReader(ct.getDataStructure());
@@ -123,9 +126,10 @@ IValueReader createReader(ValueDescriptor vd, String valueType) throws InvalidJf
if (vd.getDataType().isPrimitive()) {
return createPrimitiveReader(vd.getDataType(), vd.getContentType(), valueType);
} else if (vd.getDataType() == DataType.ARRAY) {
return new ArrayReader(createPrimitiveReader(vd.getInnerDataType(), vd.getContentType(), valueType));
return new ArrayReader(createPrimitiveReader(vd.getInnerDataType(), vd.getContentType(), valueType),
header);
} else if (vd.getDataType() == DataType.STRUCTARRAY) {
return new ArrayReader(createReader(vd.getChildren()));
return new ArrayReader(createReader(vd.getChildren()), header);
} else if (vd.getDataType() == DataType.STRUCT) {
return createReader(vd.getChildren());
} else {
@@ -85,7 +85,7 @@ public ChunkLoaderV1(ChunkStructure header, byte[] data, LoaderContext context)
int size = input.readInt();
long type = input.readLong();
if (size == 0) {
throw new CouldNotLoadRecordingException("Found event with invalid size (0)");
throw new CouldNotLoadRecordingException("Found event with invalid size (0)"); //$NON-NLS-1$
}
if (type != CONSTANT_POOL_EVENT_TYPE && type != ChunkMetadata.METADATA_EVENT_TYPE) {
manager.readEvent(type, input);
@@ -469,7 +469,7 @@ private IValueReader createFieldReader(FieldElement f, String valueType) throws
}
reader = new PoolReader(fieldType.constants, reader.getContentType());
}
return f.isArray() ? new ArrayReader(reader) : reader;
return f.isArray() ? new ArrayReader(reader, header) : reader;
}

private static String buildLabel(String id, AnnotatedElement element) {
@@ -116,15 +116,20 @@ public Object resolve(Object value) throws InvalidJfrFileException {

static class ArrayReader implements IValueReader {
private final IValueReader elementReader;
private final ChunkStructure header;

ArrayReader(IValueReader elementReader) {
ArrayReader(IValueReader elementReader, ChunkStructure header) {
this.elementReader = elementReader;
this.header = header;
}

@Override
public Object read(IDataInput in, boolean allowUnresolvedReference)
throws IOException, InvalidJfrFileException {
int size = in.readInt();
if (size > header.getChunkSize()) {
throw new InvalidJfrFileException("Found array larger than chunk size"); //$NON-NLS-1$
}
Object[] values = new Object[size];
for (int i = 0; i < values.length; i++) {
values[i] = elementReader.read(in, allowUnresolvedReference);

0 comments on commit 2352cec

Please sign in to comment.