8272594: Better record of recordings
Reviewed-by: evergizova
Backport-of: 44d9bf6d4afac7b17273b0de1189f3487c1a22f7
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/ParserFactory.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/ParserFactory.java
index 4064e88..d4e3610 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/ParserFactory.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/ParserFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2021, 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
@@ -263,6 +263,7 @@
@Override
public Object parse(RecordingInput input) throws IOException {
final int size = input.readInt();
+ input.require(size, "Array size %d exceeds available data" );
final Object[] array = new Object[size];
for (int i = 0; i < size; i++) {
array[i] = elementParser.parse(input);
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataReader.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataReader.java
index 481e370..6847189 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataReader.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataReader.java
@@ -49,6 +49,7 @@
import jdk.jfr.SettingDescriptor;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.internal.MetadataDescriptor.Element;
+import jdk.jfr.internal.consumer.RecordingInput;
/**
* Parses metadata.
@@ -64,6 +65,7 @@
public MetadataReader(DataInput input) throws IOException {
this.input = input;
int size = input.readInt();
+ ((RecordingInput)input).require(size, "Metadata string pool size %d exceeds available data" );
this.pool = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
this.pool.add(input.readUTF());
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java
index b766894..01adcfe 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2021, 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
@@ -256,6 +256,7 @@
return "";
}
int size = readInt();
+ require(size, "String size %d exceeds available data");
if (encoding == STRING_ENCODING_CHAR_ARRAY) {
char[] c = new char[size];
for (int i = 0; i < size; i++) {
@@ -336,4 +337,13 @@
int b8 = readByte(); // read last byte raw
return ret + (((long) (b8 & 0XFF)) << 56);
}
+
+ // Purpose of this method is to prevent OOM by sanity check
+ // the minimum required number of bytes against what is available in
+ // segment/chunk/file
+ public void require(int minimumBytes, String errorMessage) throws IOException {
+ if (position + minimumBytes > size) {
+ throw new IOException(String.format(errorMessage, minimumBytes));
+ }
+ }
}