Skip to content

Commit 5ec7922

Browse files
Media: Correct parsing AVIF files with empty iref box on older PHP versions.
An empty `iref` box is pointless but is allowed by the specification. This commit imports an upstream fix from libavifinfo. Follow-up to [57524], [58049]. Props yguyon. Fixes #64669. git-svn-id: https://develop.svn.wordpress.org/trunk@62029 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 6f20911 commit 5ec7922

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

src/wp-includes/class-avif-info.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Media Patent License 1.0 was not distributed with this source code in the
1010
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
1111
*
12-
* Note: this class is from libavifinfo - https://aomedia.googlesource.com/libavifinfo/+/refs/heads/main/avifinfo.php at f509487.
12+
* Note: this class is from libavifinfo - https://aomedia.googlesource.com/libavifinfo/+/refs/heads/main/avifinfo.php at 2b924de.
1313
* It is used as a fallback to parse AVIF files when the server doesn't support AVIF,
1414
* primarily to identify the width and height of the image.
1515
*
@@ -109,7 +109,7 @@ class Features {
109109
public $primary_item_id;
110110
public $primary_item_features = array( // Deduced from the data below.
111111
'width' => UNDEFINED, // In number of pixels.
112-
'height' => UNDEFINED, // Ignores mirror and rotation.
112+
'height' => UNDEFINED, // Ignores crop and rotation.
113113
'bit_depth' => UNDEFINED, // Likely 8, 10 or 12 bits per channel per pixel.
114114
'num_channels' => UNDEFINED // Likely 1, 2, 3 or 4 channels:
115115
// (1 monochrome or 3 colors) + (0 or 1 alpha)
@@ -256,6 +256,10 @@ public function parse( $handle, &$num_parsed_boxes, $num_remaining_bytes = MAX_S
256256
// Read the 32 least-significant bits.
257257
$this->size = read_big_endian( substr( $data, 4, 4 ), 4 );
258258
} else if ( $this->size == 0 ) {
259+
// ISO/IEC 14496-12 4.2.2:
260+
// if size is 0, then this box shall be in a top-level box
261+
// (i.e. not contained in another box)
262+
// Unfortunately the presence of a parent box is unknown here.
259263
$this->size = $num_remaining_bytes;
260264
}
261265
if ( $this->size < $header_size ) {
@@ -265,6 +269,9 @@ public function parse( $handle, &$num_parsed_boxes, $num_remaining_bytes = MAX_S
265269
return INVALID;
266270
}
267271

272+
// 16 bytes of usertype should be read here if the box type is 'uuid'.
273+
// 'uuid' boxes are skipped so usertype is part of the skipped body.
274+
268275
$has_fullbox_header = $this->type == 'meta' || $this->type == 'pitm' ||
269276
$this->type == 'ipma' || $this->type == 'ispe' ||
270277
$this->type == 'pixi' || $this->type == 'iref' ||
@@ -302,7 +309,7 @@ public function parse( $handle, &$num_parsed_boxes, $num_remaining_bytes = MAX_S
302309
( $this->type == 'auxC' && $this->version <= 0 );
303310
// Instead of considering this file as invalid, skip unparsable boxes.
304311
if ( !$is_parsable ) {
305-
$this->type = 'unknownversion';
312+
$this->type = 'skip'; // FreeSpaceBox. To be ignored by readers.
306313
}
307314
}
308315
// print_r( $this ); // Uncomment to print all boxes.
@@ -483,7 +490,7 @@ private function parse_ipco( $num_remaining_bytes ) {
483490
/**
484491
* Parses an "iprp" box.
485492
*
486-
* The "ipco" box contain the properties which are linked to items by the "ipma" box.
493+
* The "ipco" box contains the properties which are linked to items by the "ipma" box.
487494
*
488495
* @param stream $handle The resource the box will be parsed from.
489496
* @param int $num_remaining_bytes The number of bytes that should be available from the resource.
@@ -596,7 +603,7 @@ private function parse_iprp( $num_remaining_bytes ) {
596603
* @return Status FOUND on success or an error on failure.
597604
*/
598605
private function parse_iref( $num_remaining_bytes ) {
599-
do {
606+
while ( $num_remaining_bytes > 0 ) {
600607
$box = new Box();
601608
$status = $box->parse( $this->handle, $this->num_parsed_boxes, $num_remaining_bytes );
602609
if ( $status != FOUND ) {
@@ -656,7 +663,7 @@ private function parse_iref( $num_remaining_bytes ) {
656663
}
657664
}
658665
$num_remaining_bytes -= $box->size;
659-
} while ( $num_remaining_bytes > 0 );
666+
}
660667
return NOT_FOUND;
661668
}
662669

0 commit comments

Comments
 (0)