From a4c6a82b4f10fd690ec1e5eeb2ee2cbd8b0be742 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 6 Nov 2022 12:09:10 +0100 Subject: [PATCH] safer extended XMP parsing --- .../metadataextractor/SafeXmpReader.kt | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt index db58da6d6..4be65a348 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/SafeXmpReader.kt @@ -49,11 +49,7 @@ class SafeXmpReader : XmpReader() { extendedXMPBuffer?.let { xmpBytes -> val totalSize = xmpBytes.size if (totalSize > segmentTypeSizeDangerThreshold) { - val error = "Extended XMP is too large, with a total size of $totalSize B" - Log.w(LOG_TAG, error) - metadata.addDirectory(XmpDirectory().apply { - addError(error) - }) + logError(metadata, totalSize) } else { extract(xmpBytes, metadata) } @@ -99,7 +95,7 @@ class SafeXmpReader : XmpReader() { return null } - // adapted from `XmpReader` because original is private + // adapted from `XmpReader` to prevent large allocation private fun processExtendedXMPChunk(metadata: Metadata, segmentBytes: ByteArray, extendedXMPGUID: String, extendedXMPBufferIn: ByteArray?): ByteArray? { var extendedXMPBuffer: ByteArray? = extendedXMPBufferIn val extensionPreambleLength = XMP_EXTENSION_JPEG_PREAMBLE.length @@ -113,7 +109,15 @@ class SafeXmpReader : XmpReader() { if (extendedXMPGUID == segmentGUID) { val fullLength = reader.uInt32.toInt() val chunkOffset = reader.uInt32.toInt() - if (extendedXMPBuffer == null) extendedXMPBuffer = ByteArray(fullLength) + if (extendedXMPBuffer == null) { + // TLAD insert start + if (fullLength > segmentTypeSizeDangerThreshold) { + logError(metadata, fullLength) + return null + } + // TLAD insert end + extendedXMPBuffer = ByteArray(fullLength) + } if (extendedXMPBuffer.size == fullLength) { System.arraycopy(segmentBytes, totalOffset, extendedXMPBuffer, chunkOffset, segmentLength - totalOffset) } else { @@ -131,6 +135,14 @@ class SafeXmpReader : XmpReader() { return extendedXMPBuffer } + private fun logError(metadata: Metadata, size: Int) { + val error = "Extended XMP is too large, with a size of $size B" + Log.w(LOG_TAG, error) + metadata.addDirectory(XmpDirectory().apply { + addError(error) + }) + } + companion object { private val LOG_TAG = LogUtils.createTag()