[ 
https://issues.apache.org/jira/browse/TIKA-4838?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18108628#comment-18108628
 ] 

ASF GitHub Bot commented on TIKA-4838:
--------------------------------------

Copilot commented on code in PR #3062:
URL: https://github.com/apache/tika/pull/3062#discussion_r3868648912


##########
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp4/Mp4SampleEntries.java:
##########
@@ -0,0 +1,172 @@
+/*
+ * 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.tika.parser.mp4;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.tika.io.EndianUtils;
+
+/**
+ * Walks the sample entries of a SampleDescriptionBox ('stsd') payload, shared
+ * by the sound and video handlers. The payload is 4 bytes version and flags,
+ * a 4 byte entry count, then one sample entry per count. Each entry is a box:
+ * a 32-bit size and a FourCC, where a size of 1 announces a 64-bit largesize
+ * and a size of 0 extends the entry to the end of the payload (ISO/IEC
+ * 14496-12, 4.2).
+ */
+final class Mp4SampleEntries {
+
+    /**
+     * Size of the SampleEntry fields that follow the box header in every
+     * entry: 6 reserved bytes and the 2 byte data reference index.
+     */
+    static final int SAMPLE_ENTRY_FIELDS = 8;
+
+    interface Visitor {
+        /**
+         * @param fourCC the entry's FourCC, or null if it is not printable
+         * @param b      the stsd payload
+         * @param start  offset of the first byte after the entry's box header
+         * @param end    offset one past the entry's last byte
+         */
+        void entry(String fourCC, byte[] b, int start, int end);
+    }
+
+    private Mp4SampleEntries() {
+    }
+
+    static void walk(byte[] b, Visitor visitor) {
+        if (b.length < 8) {
+            return;
+        }
+        long entryCount = EndianUtils.getUIntBE(b, 4);
+        int pos = 8;
+        for (long i = 0; i < entryCount && pos + 8 <= b.length; i++) {
+            long size = EndianUtils.getUIntBE(b, pos);
+            int header = 8;
+            if (size == 1) {
+                //largesize: the 64-bit size follows the FourCC
+                if (pos + 16 > b.length) {
+                    return;
+                }
+                //a value beyond 63 bits goes negative and fails the size 
check below
+                size = (EndianUtils.getUIntBE(b, pos + 8) << 32) | 
EndianUtils.getUIntBE(b, pos + 12);
+                header = 16;
+            } else if (size == 0) {
+                //the entry extends to the end of the box
+                size = b.length - pos;
+            }
+            if (size < header + SAMPLE_ENTRY_FIELDS || size > b.length - pos) {
+                return;
+            }
+            int end = pos + (int) size;
+            visitor.entry(printableFourCC(b, pos + 4), b, pos + header, end);
+            pos = end;
+        }
+    }
+
+    /**
+     * Returns whether a sample entry FourCC marks a protected stream: 'drms'
+     * and 'drmi' (FairPlay) or 'enca' and 'encv' (ISO common encryption).
+     */
+    static boolean isProtected(String fourCC) {
+        return "drms".equals(fourCC) || "enca".equals(fourCC)
+                || "encv".equals(fourCC) || "drmi".equals(fourCC);
+    }
+
+    /**
+     * Looks up the original (unprotected) format of a protected sample entry:
+     * the ProtectionSchemeInfoBox 'sinf' among the entry's child boxes carries
+     * an OriginalFormatBox 'frma' whose payload is the codec FourCC that the
+     * protected format replaced (ISO/IEC 14496-12, 8.12). Returns null if
+     * there is none or it is not printable.
+     *
+     * @param pos offset of the entry's first child box
+     * @param end offset one past the entry's last byte
+     */
+    static String originalFormat(byte[] b, int pos, int end) {
+        int sinf = findBox(b, pos, end, "sinf");
+        if (sinf < 0) {
+            return null;
+        }
+        int frma = findBox(b, sinf + 8, boxEnd(b, sinf, end), "frma");
+        if (frma < 0 || frma + 12 > end) {
+            return null;
+        }
+        return printableFourCC(b, frma + 8);
+    }

Review Comment:
   `originalFormat()` validates `frma + 12 <= end` (end of the *entry*), but it 
doesn’t validate that the `frma` box itself is at least 12 bytes (8-byte header 
+ 4-byte payload). A crafted `frma` with size=8 can pass the current check and 
cause `printableFourCC(b, frma + 8)` to read 4 bytes from the following box, 
potentially exposing an incorrect codec FourCC.





> Expose the MP4 audio and video track codecs (audio:format, video:format)
> ------------------------------------------------------------------------
>
>                 Key: TIKA-4838
>                 URL: https://issues.apache.org/jira/browse/TIKA-4838
>             Project: Tika
>          Issue Type: New Feature
>            Reporter: Dominik Schmidt
>            Priority: Major
>
> The MP4/QuickTime parser does not expose the per-track codec identifiers. 
> TikaMp4SoundHandler and TikaMp4VideoHandler read the sample-entry format 
> fourcc but only use it for other purposes (audio: DRM detection; video: 
> nothing).
> Add audio:format and video:format, each carrying the four-character codec 
> identifier from the track's sample description (audio mp4a/alac/ac-3, video 
> avc1/hev1). For protected streams (drms/enca, encv/drmi) the original codec 
> is recovered from the nested frma box.
> The existing xmpDM:audioCompressor only fires for audio-typed files and 
> carries the container major brand, and xmpDM:videoCompressor carries the 
> compressor name (encoder string, e.g. "Lavc… libx264"), so neither gives the 
> per-track codec fourcc for video/* files.
> Rounds out the per-track metadata added in TIKA-4779, TIKA-4800 and TIKA-4802.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to