Version Description
(2017-08-17) =
- Fix: issues with invalid tags not being stripped out (e.g. script tags) (h/t tmmbecker, fahmi182, pppdog, seejacobscott, RavanH, jenniejj, lkraav, simonrperry for the reports).
- Fix: issues with dimension extraction for protocol-less and relative URLs (h/t ktmn for the report).
Download this release
Release Info
Developer | batmoo |
Plugin | AMP for WordPress |
Version | 0.5.1 |
Comparing to | |
See all releases |
Code changes from version 0.5 to 0.5.1
amp.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* Plugin URI: https://github.com/automattic/amp-wp
|
6 |
* Author: Automattic
|
7 |
* Author URI: https://automattic.com
|
8 |
-
* Version: 0.5
|
9 |
* Text Domain: amp
|
10 |
* Domain Path: /languages/
|
11 |
* License: GPLv2 or later
|
@@ -13,7 +13,7 @@
|
|
13 |
|
14 |
define( 'AMP__FILE__', __FILE__ );
|
15 |
define( 'AMP__DIR__', dirname( __FILE__ ) );
|
16 |
-
define( 'AMP__VERSION', '0.5' );
|
17 |
|
18 |
require_once( AMP__DIR__ . '/back-compat/back-compat.php' );
|
19 |
require_once( AMP__DIR__ . '/includes/amp-helper-functions.php' );
|
5 |
* Plugin URI: https://github.com/automattic/amp-wp
|
6 |
* Author: Automattic
|
7 |
* Author URI: https://automattic.com
|
8 |
+
* Version: 0.5.1
|
9 |
* Text Domain: amp
|
10 |
* Domain Path: /languages/
|
11 |
* License: GPLv2 or later
|
13 |
|
14 |
define( 'AMP__FILE__', __FILE__ );
|
15 |
define( 'AMP__DIR__', dirname( __FILE__ ) );
|
16 |
+
define( 'AMP__VERSION', '0.5.1' );
|
17 |
|
18 |
require_once( AMP__DIR__ . '/back-compat/back-compat.php' );
|
19 |
require_once( AMP__DIR__ . '/includes/amp-helper-functions.php' );
|
includes/sanitizers/class-amp-tag-and-attribute-sanitizer.php
CHANGED
@@ -83,7 +83,6 @@ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
|
|
83 |
|
84 |
// Remove nodes with non-whitelisted tags.
|
85 |
if ( ! $this->is_amp_allowed_tag( $node ) ) {
|
86 |
-
|
87 |
// If it's not an allowed tag, replace the node with it's children
|
88 |
$this->replace_node_with_children( $node );
|
89 |
// Return early since this node no longer exists.
|
@@ -109,52 +108,61 @@ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
|
|
109 |
}
|
110 |
|
111 |
// The remaining validations all have to do with attributes.
|
112 |
-
|
113 |
-
$attr_spec_list = array();
|
114 |
-
|
115 |
-
// If we have exactly one rule_spec, use it's attr_spec_list to
|
116 |
-
// validate the node's attributes.
|
117 |
-
if ( 1 == count( $rule_spec_list_to_validate ) ) {
|
118 |
-
$rule_spec = array_pop( $rule_spec_list_to_validate );
|
119 |
-
$attr_spec_list = $rule_spec[AMP_Rule_Spec::ATTR_SPEC_LIST];
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
// If there is more than one valid rule_spec for this node, then
|
122 |
// try to deduce which one is intended by inspecting the node's
|
123 |
// attributes.
|
124 |
-
} else {
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
// Get the key(s) to the highest score(s).
|
134 |
-
$spec_ids_sorted = array_keys( $attr_spec_scores, max( $attr_spec_scores ) );
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
$attr_spec_list = $rule_spec_list_to_validate[ $spec_ids_sorted[0] ][AMP_Rule_Spec::ATTR_SPEC_LIST];
|
139 |
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
149 |
}
|
150 |
}
|
|
|
151 |
|
152 |
-
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
154 |
|
155 |
-
|
156 |
-
|
|
|
|
|
157 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
159 |
|
160 |
/**
|
@@ -167,7 +175,6 @@ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
|
|
167 |
* return true.
|
168 |
*/
|
169 |
private function validate_tag_spec_for_node( $node, $tag_spec ) {
|
170 |
-
|
171 |
if ( ! empty( $tag_spec[AMP_Rule_Spec::MANDATORY_PARENT] ) &&
|
172 |
! $this->has_parent( $node, $tag_spec[AMP_Rule_Spec::MANDATORY_PARENT] ) ) {
|
173 |
return false;
|
@@ -364,66 +371,58 @@ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
|
|
364 |
}
|
365 |
}
|
366 |
|
|
|
|
|
367 |
foreach( $node->attributes as $attr_name => $attr_node ) {
|
368 |
|
369 |
if ( ! isset( $attr_spec_list[$attr_name] ) ) {
|
370 |
continue;
|
371 |
}
|
372 |
|
373 |
-
$
|
|
|
374 |
|
375 |
if ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE] ) &&
|
376 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value( $node, $attr_name, $attr_spec_rule ) ) {
|
377 |
-
$
|
378 |
-
|
379 |
-
}
|
380 |
-
|
381 |
-
if ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE_CASEI] ) &&
|
382 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value_casei( $node, $attr_name, $attr_spec_rule ) ) {
|
383 |
-
$
|
384 |
-
|
385 |
-
}
|
386 |
-
|
387 |
-
if ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE_REGEX] ) &&
|
388 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value_regex( $node, $attr_name, $attr_spec_rule ) ) {
|
389 |
-
$
|
390 |
-
|
391 |
-
}
|
392 |
-
|
393 |
-
if ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE_REGEX_CASEI] ) &&
|
394 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value_regex_casei( $node, $attr_name, $attr_spec_rule ) ) {
|
395 |
-
$
|
396 |
-
|
397 |
-
}
|
398 |
-
|
399 |
-
if ( isset( $attr_spec_rule[AMP_Rule_Spec::ALLOWED_PROTOCOL] ) &&
|
400 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_allowed_protocol( $node, $attr_name, $attr_spec_rule ) ) {
|
401 |
-
$
|
402 |
-
|
403 |
-
}
|
404 |
-
|
405 |
-
if ( isset( $attr_spec_rule[AMP_Rule_Spec::ALLOW_RELATIVE] ) &&
|
406 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_disallowed_relative( $node, $attr_name, $attr_spec_rule ) ) {
|
407 |
-
$
|
408 |
-
|
409 |
-
}
|
410 |
-
|
411 |
-
if ( isset( $attr_spec_rule[AMP_Rule_Spec::ALLOW_EMPTY] ) &&
|
412 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_disallowed_empty( $node, $attr_name, $attr_spec_rule ) ) {
|
413 |
-
$
|
414 |
-
|
415 |
-
}
|
416 |
-
|
417 |
-
if ( isset( $attr_spec_rule[AMP_Rule_Spec::DISALLOWED_DOMAIN] ) &&
|
418 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_disallowed_domain( $node, $attr_name, $attr_spec_rule ) ) {
|
419 |
-
$
|
420 |
-
|
|
|
|
|
421 |
}
|
422 |
|
423 |
-
if (
|
424 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
425 |
$attrs_to_remove[] = $attr_name;
|
426 |
-
continue;
|
427 |
}
|
428 |
}
|
429 |
|
83 |
|
84 |
// Remove nodes with non-whitelisted tags.
|
85 |
if ( ! $this->is_amp_allowed_tag( $node ) ) {
|
|
|
86 |
// If it's not an allowed tag, replace the node with it's children
|
87 |
$this->replace_node_with_children( $node );
|
88 |
// Return early since this node no longer exists.
|
108 |
}
|
109 |
|
110 |
// The remaining validations all have to do with attributes.
|
111 |
+
$attr_spec_list = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
+
// If we have exactly one rule_spec, use it's attr_spec_list to
|
114 |
+
// validate the node's attributes.
|
115 |
+
if ( 1 == count( $rule_spec_list_to_validate ) ) {
|
116 |
+
$rule_spec = array_pop( $rule_spec_list_to_validate );
|
117 |
+
$attr_spec_list = $rule_spec[AMP_Rule_Spec::ATTR_SPEC_LIST];
|
118 |
+
} else {
|
119 |
// If there is more than one valid rule_spec for this node, then
|
120 |
// try to deduce which one is intended by inspecting the node's
|
121 |
// attributes.
|
|
|
122 |
|
123 |
+
// Get a score from each attr_spec_list by seeing how many
|
124 |
+
// attributes and values match the node.
|
125 |
+
$attr_spec_scores = array();
|
126 |
+
foreach ( $rule_spec_list_to_validate as $spec_id => $rule_spec ) {
|
127 |
+
$attr_spec_scores[ $spec_id ] = $this->validate_attr_spec_list_for_node( $node, $rule_spec[AMP_Rule_Spec::ATTR_SPEC_LIST] );
|
128 |
+
}
|
|
|
|
|
|
|
129 |
|
130 |
+
// Get the key(s) to the highest score(s).
|
131 |
+
$spec_ids_sorted = array_keys( $attr_spec_scores, max( $attr_spec_scores ) );
|
|
|
132 |
|
133 |
+
// If there is exactly one attr_spec with a max score, use that one.
|
134 |
+
if ( 1 == count( $spec_ids_sorted ) ) {
|
135 |
+
$attr_spec_list = $rule_spec_list_to_validate[ $spec_ids_sorted[0] ][AMP_Rule_Spec::ATTR_SPEC_LIST];
|
136 |
+
// Otherwise...
|
137 |
+
} else {
|
138 |
+
// This should not happen very often, but...
|
139 |
+
// If we're here, then we're not sure which spec should
|
140 |
+
// be used. Let's use the top scoring ones.
|
141 |
+
foreach( $spec_ids_sorted as $id ) {
|
142 |
+
$attr_spec_list = array_merge( $attr_spec_list, $rule_spec_list_to_validate[ $id ][AMP_Rule_Spec::ATTR_SPEC_LIST] );
|
143 |
}
|
144 |
}
|
145 |
+
}
|
146 |
|
147 |
+
// If an attribute is mandatory and we don't have it, just remove the node and move on.
|
148 |
+
foreach ( $attr_spec_list as $attr_name => $attr_spec_rule_value ) {
|
149 |
+
$is_mandatory =
|
150 |
+
isset( $attr_spec_rule_value[ AMP_Rule_Spec::MANDATORY ] )
|
151 |
+
? (bool) $attr_spec_rule_value[ AMP_Rule_Spec::MANDATORY ]
|
152 |
+
: false;
|
153 |
+
$attribute_exists = $node->hasAttribute( $attr_name );
|
154 |
|
155 |
+
if ( $is_mandatory && ! $attribute_exists ) {
|
156 |
+
$this->remove_node( $node );
|
157 |
+
return;
|
158 |
+
}
|
159 |
}
|
160 |
+
|
161 |
+
// Remove any remaining disallowed attributes.
|
162 |
+
$this->sanitize_disallowed_attributes_in_node( $node, $attr_spec_list );
|
163 |
+
|
164 |
+
// Remove values that don't conform to the attr_spec.
|
165 |
+
$this->sanitize_disallowed_attribute_values_in_node( $node, $attr_spec_list );
|
166 |
}
|
167 |
|
168 |
/**
|
175 |
* return true.
|
176 |
*/
|
177 |
private function validate_tag_spec_for_node( $node, $tag_spec ) {
|
|
|
178 |
if ( ! empty( $tag_spec[AMP_Rule_Spec::MANDATORY_PARENT] ) &&
|
179 |
! $this->has_parent( $node, $tag_spec[AMP_Rule_Spec::MANDATORY_PARENT] ) ) {
|
180 |
return false;
|
371 |
}
|
372 |
}
|
373 |
|
374 |
+
$mandatory_attributes = array();
|
375 |
+
|
376 |
foreach( $node->attributes as $attr_name => $attr_node ) {
|
377 |
|
378 |
if ( ! isset( $attr_spec_list[$attr_name] ) ) {
|
379 |
continue;
|
380 |
}
|
381 |
|
382 |
+
$should_remove_node = false;
|
383 |
+
$attr_spec_rule = $attr_spec_list[ $attr_name ];
|
384 |
|
385 |
if ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE] ) &&
|
386 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value( $node, $attr_name, $attr_spec_rule ) ) {
|
387 |
+
$should_remove_node = true;
|
388 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE_CASEI] ) &&
|
|
|
|
|
|
|
389 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value_casei( $node, $attr_name, $attr_spec_rule ) ) {
|
390 |
+
$should_remove_node = true;
|
391 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE_REGEX] ) &&
|
|
|
|
|
|
|
392 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value_regex( $node, $attr_name, $attr_spec_rule ) ) {
|
393 |
+
$should_remove_node = true;
|
394 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::VALUE_REGEX_CASEI] ) &&
|
|
|
|
|
|
|
395 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_value_regex_casei( $node, $attr_name, $attr_spec_rule ) ) {
|
396 |
+
$should_remove_node = true;
|
397 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::ALLOWED_PROTOCOL] ) &&
|
|
|
|
|
|
|
398 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_allowed_protocol( $node, $attr_name, $attr_spec_rule ) ) {
|
399 |
+
$should_remove_node = true;
|
400 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::ALLOW_RELATIVE] ) &&
|
|
|
|
|
|
|
401 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_disallowed_relative( $node, $attr_name, $attr_spec_rule ) ) {
|
402 |
+
$should_remove_node = true;
|
403 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::ALLOW_EMPTY] ) &&
|
|
|
|
|
|
|
404 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_disallowed_empty( $node, $attr_name, $attr_spec_rule ) ) {
|
405 |
+
$should_remove_node = true;
|
406 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::DISALLOWED_DOMAIN] ) &&
|
|
|
|
|
|
|
407 |
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_disallowed_domain( $node, $attr_name, $attr_spec_rule ) ) {
|
408 |
+
$should_remove_node = true;
|
409 |
+
} elseif ( isset( $attr_spec_rule[AMP_Rule_Spec::BLACKLISTED_VALUE_REGEX] ) &&
|
410 |
+
AMP_Rule_Spec::FAIL == $this->check_attr_spec_rule_blacklisted_value_regex( $node, $attr_name, $attr_spec_rule ) ) {
|
411 |
+
$should_remove_node = true;
|
412 |
}
|
413 |
|
414 |
+
if ( $should_remove_node ) {
|
415 |
+
$is_mandatory =
|
416 |
+
isset( $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ] )
|
417 |
+
? (bool) $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ]
|
418 |
+
: false;
|
419 |
+
|
420 |
+
if ( $is_mandatory ) {
|
421 |
+
$this->remove_node( $node );
|
422 |
+
return;
|
423 |
+
}
|
424 |
+
|
425 |
$attrs_to_remove[] = $attr_name;
|
|
|
426 |
}
|
427 |
}
|
428 |
|
includes/utils/class-amp-image-dimension-extractor.php
CHANGED
@@ -10,18 +10,32 @@ class AMP_Image_Dimension_Extractor {
|
|
10 |
self::register_callbacks();
|
11 |
}
|
12 |
|
13 |
-
$
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
}
|
19 |
}
|
20 |
|
21 |
-
$
|
22 |
-
$
|
23 |
|
24 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
|
27 |
public static function normalize_url( $url ) {
|
10 |
self::register_callbacks();
|
11 |
}
|
12 |
|
13 |
+
$return_dimensions = array();
|
14 |
+
|
15 |
+
// Normalize URLs and also track a map of normalized-to-original as we'll need it to reformat things when returning the data.
|
16 |
+
$url_map = array();
|
17 |
+
$normalized_urls = array();
|
18 |
+
foreach ( $urls as $original_url ) {
|
19 |
+
$normalized_url = self::normalize_url( $original_url );
|
20 |
+
if ( false !== $normalized_url ) {
|
21 |
+
$url_map[ $normalized_url ] = $original_url;
|
22 |
+
$normalized_urls[] = $normalized_url;
|
23 |
+
} else {
|
24 |
+
// This is not a URL we can extract dimensions from, so default to false.
|
25 |
+
$return_dimensions[ $original_url ] = false;
|
26 |
}
|
27 |
}
|
28 |
|
29 |
+
$extracted_dimensions = array_fill_keys( $normalized_urls, false );
|
30 |
+
$extracted_dimensions = apply_filters( 'amp_extract_image_dimensions_batch', $extracted_dimensions );
|
31 |
|
32 |
+
// We need to return a map with the original (un-normalized URL) as we that to match nodes that need dimensions.
|
33 |
+
foreach ( $extracted_dimensions as $normalized_url => $dimension ) {
|
34 |
+
$original_url = $url_map[ $normalized_url ];
|
35 |
+
$return_dimensions[ $original_url ] = $dimension;
|
36 |
+
}
|
37 |
+
|
38 |
+
return $return_dimensions;
|
39 |
}
|
40 |
|
41 |
public static function normalize_url( $url ) {
|
readme.txt
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
=== AMP ===
|
2 |
-
Contributors: batmoo, joen, automattic, potatomaster
|
3 |
Tags: amp, mobile
|
4 |
Requires at least: 4.7
|
5 |
Tested up to: 4.8
|
6 |
-
Stable tag: 0.5
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -53,6 +53,11 @@ A wise green Yoda once said, "Patience you must have, my young padawan." We're w
|
|
53 |
|
54 |
== Changelog ==
|
55 |
|
|
|
|
|
|
|
|
|
|
|
56 |
= 0.5 (2017-08-04) =
|
57 |
|
58 |
- Whitelist Sanitizer: Replace Blacklist Sanitizer with a whitelist-based approach using the AMP spec (props delputnam)
|
1 |
=== AMP ===
|
2 |
+
Contributors: batmoo, joen, automattic, potatomaster, albertomedina
|
3 |
Tags: amp, mobile
|
4 |
Requires at least: 4.7
|
5 |
Tested up to: 4.8
|
6 |
+
Stable tag: 0.5.1
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
53 |
|
54 |
== Changelog ==
|
55 |
|
56 |
+
= 0.5.1 (2017-08-17) =
|
57 |
+
|
58 |
+
- Fix: issues with invalid tags not being stripped out (e.g. script tags) (h/t tmmbecker, fahmi182, pppdog, seejacobscott, RavanH, jenniejj, lkraav, simonrperry for the reports).
|
59 |
+
- Fix: issues with dimension extraction for protocol-less and relative URLs (h/t ktmn for the report).
|
60 |
+
|
61 |
= 0.5 (2017-08-04) =
|
62 |
|
63 |
- Whitelist Sanitizer: Replace Blacklist Sanitizer with a whitelist-based approach using the AMP spec (props delputnam)
|