Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8867965
VPLAY-12333 mp4demux hardening
pstroffolino Jan 10, 2026
562b881
Reason for Change: AC-4 support
pstroffolino Jan 10, 2026
789a87e
Reason for Change: few additional optimizations/improvements
pstroffolino Jan 10, 2026
7309613
Reason for Change: setParseError cleanup
pstroffolino Jan 11, 2026
1137d11
Merge branch 'dev_sprint_25_2' into feature/VPLAY-12333
pstroffolino Jan 11, 2026
7250d01
Reason for Change: fix for ac-4 parsing
pstroffolino Jan 11, 2026
dfb2427
Merge branch 'dev_sprint_25_2' into feature/VPLAY-12333
pstroffolino Jan 11, 2026
6d80135
Readon for Change: more copilot nitpicks
pstroffolino Jan 11, 2026
0cf5294
Merge branch 'feature/VPLAY-12333' of https://github.com/rdkcentral/a…
pstroffolino Jan 11, 2026
b008810
Reason for Change: beefed up tests
pstroffolino Jan 11, 2026
1762ff5
Reason for Change: added support for 'skip' box (same behavior as "free"
pstroffolino Jan 11, 2026
107adc9
Reason for Change: removed no-longer needed hack from utest
pstroffolino Jan 11, 2026
74227ca
Reason for Change: edge case fix
pstroffolino Jan 12, 2026
bb87599
Reason for Change: comments
pstroffolino Jan 12, 2026
9befbf7
Reason for Change: tightened/completed bounds check for size variations
pstroffolino Jan 12, 2026
4379972
Reason for Change: bounds checks
pstroffolino Jan 12, 2026
b5db7e0
Reason for Change: more coppilot iterations
pstroffolino Jan 12, 2026
8eb2b65
Reason for Change: parseError handling
pstroffolino Jan 12, 2026
c88341c
Reason for Change: refactored parse errors to use exceptions
pstroffolino Jan 12, 2026
19c71f4
Reason for Change: ParseTrackEncryptionBox fix
pstroffolino Jan 12, 2026
45ff94d
Reason for Change: restored doxygen comments
pstroffolino Jan 12, 2026
e485800
Reason for Change: minor syntax issues
pstroffolino Jan 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
419 changes: 322 additions & 97 deletions mp4demux/MP4Demux.cpp

Large diffs are not rendered by default.

44 changes: 32 additions & 12 deletions mp4demux/MP4Demux.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,20 @@ enum mp4LogLevel
*/
enum Mp4ParseError
{
MP4_PARSE_OK = 0, /**< No error */
MP4_PARSE_ERROR_INVALID_BOX, /**< Invalid box encountered */
MP4_PARSE_ERROR_INVALID_CONSTANT_IV_SIZE, /**< Invalid constant IV size */
MP4_PARSE_ERROR_SAMPLE_COUNT_MISMATCH, /**< Sample count mismatch */
MP4_PARSE_ERROR_UNSUPPORTED_ENCRYPTION_SCHEME, /**< Invalid auxiliary info type */
MP4_PARSE_ERROR_MISSING_DATA_OFFSET, /**< Missing data offset in TRUN */
MP4_PARSE_ERROR_INVALID_PADDING, /**< Invalid padding value */
MP4_PARSE_ERROR_UNSUPPORTED_SAMPLE_ENTRY_COUNT,/**< Unsupported sample entry count */
MP4_PARSE_OK, /**< No error */
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed explicit initializer (= 0) for the first enum value. While this is technically correct (first enum value defaults to 0), removing the explicit initialization changes the existing pattern and could be considered a breaking change if external code depends on this specific pattern for compatibility checks. For consistency with the previous explicit initialization, consider keeping "MP4_PARSE_OK = 0".

Suggested change
MP4_PARSE_OK, /**< No error */
MP4_PARSE_OK = 0, /**< No error */

Copilot uses AI. Check for mistakes.
MP4_PARSE_ERROR_INVALID_BOX, /**< Invalid box header size */
MP4_PARSE_ERROR_INVALID_IV_SIZE, /**< Invalid IV size (expected 8 or 16) */
MP4_PARSE_ERROR_SAMPLE_COUNT_MISMATCH, /**< Explicit sample count doesn't match implicit sample count */
MP4_PARSE_ERROR_UNSUPPORTED_ENCRYPTION_SCHEME, /**< Expected cenc or cbcs */
MP4_PARSE_ERROR_INVALID_PADDING, /**< Unexpected Video Padding field (should be 0xffff) */
MP4_PARSE_ERROR_UNSUPPORTED_SAMPLE_ENTRY_COUNT,/**< Zero sample entry count */
MP4_PARSE_ERROR_UNSUPPORTED_STREAM_FORMAT, /**< Unsupported stream format */
MP4_PARSE_ERROR_INVALID_ESDS_TAG, /**< Invalid ESDS tag */
MP4_PARSE_ERROR_DATA_BOUNDARY_MISMATCH, /**< Data boundary mismatch */
MP4_PARSE_ERROR_INVALID_INPUT /**< Invalid input to parse function */
MP4_PARSE_ERROR_DATA_BOUNDARY_MISMATCH, /**< Data boundary mismatch - referencing invalid memory */
MP4_PARSE_ERROR_INVALID_INPUT, /**< Invalid input to parse function; nullptr or zero length */
MP4_PARSE_ERROR_INVALID_KID, /**< Invalid (huge) kidCount */
MP4_PARSE_ERROR_INVALID_ENTRY_COUNT, /**< Entry count is zero */
MP4_PARSE_ERROR_VARIABLE_LENGTH_OVERFLOW /**< Value encoded using octets exceed 32 bits */
};

/**
Expand Down Expand Up @@ -143,6 +145,10 @@ class Mp4Demux
// Parser state
const uint8_t *moofPtr; /**< Base address for sample data */
const uint8_t *ptr; /**< Current parser position */
const uint8_t *endPtr; /**< Absolute end boundary of the current parse buffer */
// MDAT range tracking (for sample data validation)
const uint8_t *mdatStart; /**< Pointer to the first byte of the payload of the current or most recently parsed 'mdat' box. Set when an 'mdat' box is parsed and used as the lower bound when validating that computed sample data offsets and sizes remain within the available payload range. */
const uint8_t *mdatEnd; /**< Pointer to one past the last byte of the payload of the current or most recently parsed 'mdat' box. Set together with mdatStart during 'mdat' parsing and used as the upper bound during sample data bounds checking to ensure no read extends beyond the validated 'mdat' payload. */

// Box header fields
uint8_t version; /**< Box version */
Expand All @@ -167,6 +173,12 @@ class Mp4Demux
MediaCodecInfo codecInfo; /**< Codec information */
Mp4ParseError parseError; /**< Current parse error state */

/**
* @brief log human readable parse error and update state
* @param parseError one of Mp4ParseError
*/
void setParseError( Mp4ParseError );

/**
* @brief Read n bytes from current position in big-endian format
* @param n Number of bytes to read
Expand Down Expand Up @@ -321,7 +333,7 @@ class Mp4Demux
* @brief Read length field with variable encoding
* @return Length value
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ReadLen() method return type has been changed from int to uint32_t. This is a good improvement for type safety since lengths should never be negative. However, this is a breaking API change for any code that may have assigned the result to an int variable. Ensure this change is documented in release notes.

Suggested change
* @return Length value
*
* This method reads a length field that is encoded using a variable-length
* scheme. The returned value is always non-negative and represented as
* an unsigned 32-bit integer.
*
* @return Length value as uint32_t
*
* @note The return type of this method was changed from int to uint32_t
* to improve type safety (lengths are never negative). Callers
* should ensure they do not rely on negative values and avoid
* unintended narrowing conversions to signed types.

Copilot uses AI. Check for mistakes.
*/
int ReadLen();
uint32_t ReadLen();
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ReadLen function's return type changes from int to uint32_t, which is a breaking API change. While this is an improvement (length should be unsigned), any calling code that stores the result in an int variable may experience issues. Ensure all callers have been reviewed and updated appropriately.

Suggested change
uint32_t ReadLen();
int ReadLen();

Copilot uses AI. Check for mistakes.

/**
* @brief Parse codec configuration helper
Expand Down Expand Up @@ -383,6 +395,14 @@ class Mp4Demux
* @brief Parse MP4 data
* @param ptr Pointer to MP4 data
* @param len Length of data
*
* @note Internally, an end-of-buffer pointer (endPtr) is computed as
* &((const uint8_t*)ptr)[len]. All parsing routines use this
* endPtr for uniform bounds checking, ensuring that every read
* and pointer increment is validated against the end of the
* input buffer to prevent buffer overruns and out-of-bounds
* memory access.
*
* @return true if parsing succeeded, false on error
*/
bool Parse(const void *ptr, size_t len);
Expand Down Expand Up @@ -428,4 +448,4 @@ class Mp4Demux
std::vector<AampMediaSample> GetSamples();
};

#endif /* __MP4_DEMUX_H__ */
#endif /* __MP4_DEMUX_H__ */
Loading
Loading