This is an automated email from the ASF dual-hosted git repository.

pjfanning pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 874b21c5bd Fix out-of-bounds fill in EmfPlusPath RLE point-type 
expansion (#1082)
874b21c5bd is described below

commit 874b21c5bd615f08e9ab5e1da522fffb5c4c6099
Author: jmestwa-coder <[email protected]>
AuthorDate: Tue May 26 02:58:21 2026 +0530

    Fix out-of-bounds fill in EmfPlusPath RLE point-type expansion (#1082)
    
    fix out-of-bounds fill in emfplus path rle point-type expansion
---
 .../poi/hemf/record/emfplus/HemfPlusPath.java      |  2 +-
 .../poi/hemf/record/emfplus/TestHemfPlusPath.java  | 60 ++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git 
a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java
 
b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java
index a69f4954e1..210e3a5063 100644
--- 
a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java
+++ 
b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java
@@ -130,7 +130,7 @@ public class HemfPlusPath {
             if (isRLE) {
                 for (int i=0, rleCount; i<pointCount; i+=rleCount, size+=2) {
                     rleCount = POINT_RLE_COUNT.getValue(leis.readByte());
-                    Arrays.fill(pointTypes, pointCount, pointCount+rleCount, 
leis.readByte());
+                    Arrays.fill(pointTypes, i, Math.min(i+rleCount, 
pointCount), leis.readByte());
                 }
             } else {
                 leis.readFully(pointTypes);
diff --git 
a/poi-scratchpad/src/test/java/org/apache/poi/hemf/record/emfplus/TestHemfPlusPath.java
 
b/poi-scratchpad/src/test/java/org/apache/poi/hemf/record/emfplus/TestHemfPlusPath.java
new file mode 100644
index 0000000000..26792374c4
--- /dev/null
+++ 
b/poi-scratchpad/src/test/java/org/apache/poi/hemf/record/emfplus/TestHemfPlusPath.java
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hemf.record.emfplus;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectType;
+import org.apache.poi.hemf.record.emfplus.HemfPlusPath.EmfPlusPath;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInputStream;
+import org.junit.jupiter.api.Test;
+
+class TestHemfPlusPath {
+
+    /**
+     * A run-length-encoded EmfPlusPath expands the per-point type table from a
+     * sequence of (runCount, type) pairs. The fill must start at the running
+     * offset; a crafted path with the RLE_COMPRESSED flag set used to write at
+     * the array end, overrunning the pointTypes buffer.
+     */
+    @Test
+    void rleCompressedPathFillsWithinBounds() throws Exception {
+        final int pointCount = 2;
+        byte[] data = new byte[64];
+        int pos = 0;
+        // EmfPlusGraphicsVersion: metafile signature 0xDBC01, graphics 
version 1
+        LittleEndian.putInt(data, pos, 0xDBC01001); pos += 4;
+        LittleEndian.putInt(data, pos, pointCount); pos += 4;
+        // pointFlags: RLE_COMPRESSED (0x1000), neither relative nor compressed
+        LittleEndian.putShort(data, pos, (short) 0x1000); pos += 2;
+        pos += 2; // skipped
+        // pointCount absolute EmfPlusPointF entries (two floats each)
+        pos += pointCount * 8;
+        // single RLE run covering both points: runCount=2, type byte
+        data[pos++] = 0x02;
+        data[pos++] = 0x00;
+
+        EmfPlusPath path = new EmfPlusPath();
+        try (LittleEndianInputStream leis = new LittleEndianInputStream(new 
ByteArrayInputStream(data))) {
+            assertDoesNotThrow(() -> path.init(leis, data.length, 
EmfPlusObjectType.PATH, 0));
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to