Skip to content

Commit e7cb4a7

Browse files
committed
Harden processing of PICTURE tag
1 parent b4660de commit e7cb4a7

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

plugins/image-prioritizer/class-image-prioritizer-img-tag-visitor.php

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ private function process_img( OD_HTML_Tag_Processor $processor, OD_Tag_Visitor_C
191191
* @return bool Whether the tag should be tracked in URL Metrics.
192192
*/
193193
private function process_picture( OD_HTML_Tag_Processor $processor, OD_Tag_Visitor_Context $context ): bool {
194+
/**
195+
* First SOURCE tag's attributes.
196+
*
197+
* @var array{ srcset: non-empty-string, sizes: string|null, type: non-empty-string }|null $first_source
198+
*/
194199
$first_source = null;
195200
$img_xpath = null;
196201

@@ -206,20 +211,35 @@ private function process_picture( OD_HTML_Tag_Processor $processor, OD_Tag_Visit
206211
break;
207212
}
208213

209-
// Collect SOURCE elements.
214+
// Process the SOURCE elements.
210215
if ( 'SOURCE' === $tag && ! $processor->is_tag_closer() ) {
211-
$media = $processor->get_attribute( 'media' );
212-
$type = $processor->get_attribute( 'type' );
216+
// Abort processing if the PICTURE involves art direction since then adding a preload link is infeasible.
217+
if ( null !== $processor->get_attribute( 'media' ) ) {
218+
return false;
219+
}
220+
221+
// Abort processing if a SOURCE lacks the required srcset attribute.
222+
$srcset = $processor->get_attribute( 'srcset' );
223+
if ( ! is_string( $srcset ) ) {
224+
return false;
225+
}
226+
$srcset = trim( $srcset );
227+
if ( '' === $srcset ) {
228+
return false;
229+
}
213230

214-
// Ensure that all SOURCE elements have a type attribute and no media attribute.
215-
if ( null !== $media || null === $type ) {
231+
// Abort processing if there is no valid image type.
232+
$type = $this->get_attribute_value( $processor, 'type' );
233+
if ( ! is_string( $type ) || ! str_starts_with( $type, 'image/' ) ) {
216234
return false;
217235
}
218236

237+
// Collect the first valid SOURCE as the preload link.
219238
if ( null === $first_source ) {
239+
$sizes = $processor->get_attribute( 'sizes' );
220240
$first_source = array(
221-
'srcset' => $processor->get_attribute( 'srcset' ),
222-
'sizes' => $processor->get_attribute( 'sizes' ),
241+
'srcset' => $srcset,
242+
'sizes' => is_string( $sizes ) ? $sizes : null,
223243
'type' => $type,
224244
);
225245
}
@@ -243,6 +263,7 @@ private function process_picture( OD_HTML_Tag_Processor $processor, OD_Tag_Visit
243263
}
244264
}
245265

266+
// Abort if we never encountered a SOURCE or IMG tag.
246267
if ( null === $img_xpath || null === $first_source ) {
247268
return false;
248269
}

plugins/image-prioritizer/class-image-prioritizer-tag-visitor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/**
1515
* Tag visitor that optimizes image tags.
1616
*
17-
* @phpstan-type NormalizedAttributeNames 'fetchpriority'|'loading'|'crossorigin'|'preload'|'referrerpolicy'
17+
* @phpstan-type NormalizedAttributeNames 'fetchpriority'|'loading'|'crossorigin'|'preload'|'referrerpolicy'|'type'
1818
*
1919
* @since 0.1.0
2020
* @access private

0 commit comments

Comments
 (0)