PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | jetpack_vendor/automattic/jetpack-device-detection/src/class-device-detection.php +58 -32 13.5.2 → 16.3 View file →
@@ -23,8 +23,22 @@
23 23 */
24 24 class Device_Detection {
25 25
26 26 /**
27 + * Memoization cache for get_info() results.
28 + *
29 + * @var array
30 + */
31 + private static $get_info_memo = array();
32 +
33 + /**
34 + * Maximum size of the memoization cache.
35 + *
36 + * @var int
37 + */
38 + private static $max_memo_size = 100;
39 +
40 + /**
27 41 * Returns information about the current device accessing the page.
28 42 *
29 43 * @param string $ua (Optional) User-Agent string.
30 44 *
@@ -40,8 +54,18 @@
40 54 * 'is_phone_matched_ua' => (string) Matched UA.
41 55 * );
42 56 */
43 57 public static function get_info( $ua = '' ) {
58 + // Return memoized result if available.
59 + // phpcs:disable WordPress.Security.ValidatedSanitizedInput
60 + $memo_key = ! empty( $ua ) ? $ua : ( $_SERVER['HTTP_USER_AGENT'] ?? '' );
61 + // Note: UA string used raw for compatibility reasons.
62 + // No sanitization is needed as the value is never output or persisted, and is only used for memoization.
63 + // phpcs:enable WordPress.Security.ValidatedSanitizedInput
64 + if ( isset( self::$get_info_memo[ $memo_key ] ) ) {
65 + return self::$get_info_memo[ $memo_key ];
66 + }
67 +
44 68 $ua_info = new User_Agent_Info( $ua );
45 69
46 70 $info = array(
47 71 'is_phone' => self::is_mobile( 'any', false, $ua_info ),
@@ -67,8 +91,15 @@
67 91 * @param User_Agent_Info $ua_info Instance of Automattic\Jetpack\Device_Detection\User_Agent_Info.
68 92 */
69 93 $info = apply_filters( 'jetpack_device_detection_get_info', $info, $ua, $ua_info );
70 94 }
95 +
96 + // Memoize the result.
97 + self::$get_info_memo[ $memo_key ] = $info;
98 + if ( count( self::$get_info_memo ) > self::$max_memo_size ) {
99 + array_shift( self::$get_info_memo );
100 + }
101 +
71 102 return $info;
72 103 }
73 104
74 105 /**
@@ -145,9 +176,8 @@
145 176 'smart' => false,
146 177 'dumb' => false,
147 178 'any' => false,
148 179 );
149 - $first_run = true;
150 180 $matched_agent = '';
151 181
152 182 // If an invalid kind is passed in, reset it to default.
153 183 if ( ! isset( $kinds[ $kind ] ) ) {
@@ -157,15 +187,15 @@
157 187 if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
158 188 return false;
159 189 }
160 190
161 - $agent = strtolower( filter_var( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) );
162 - if ( strpos( $agent, 'ipad' ) ) {
191 + $agent = strtolower( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- This is validating.
192 + if ( strpos( $agent, 'ipad' ) !== false ) {
163 193 return false;
164 194 }
165 195
166 196 // Remove Samsung Galaxy tablets (SCH-I800) from being mobile devices.
167 - if ( strpos( $agent, 'sch-i800' ) ) {
197 + if ( strpos( $agent, 'sch-i800' ) !== false ) {
168 198 return false;
169 199 }
170 200
171 201 if ( $ua_info->is_android_tablet() && false === $ua_info->is_kindle_touch() ) {
@@ -175,44 +205,40 @@
175 205 if ( $ua_info->is_blackberry_tablet() ) {
176 206 return false;
177 207 }
178 208
179 - if ( $first_run ) {
180 - $first_run = false;
209 + // checks for iPhoneTier devices & RichCSS devices.
210 + if ( $ua_info->isTierIphone() || $ua_info->isTierRichCSS() ) {
211 + $kinds['smart'] = true;
212 + $matched_agent = $ua_info->matched_agent;
213 + }
181 214
182 - // checks for iPhoneTier devices & RichCSS devices.
183 - if ( $ua_info->isTierIphone() || $ua_info->isTierRichCSS() ) {
184 - $kinds['smart'] = true;
185 - $matched_agent = $ua_info->matched_agent;
186 - }
215 + if ( ! $kinds['smart'] ) {
216 + // if smart, we are not dumb so no need to check.
217 + $dumb_agents = $ua_info->dumb_agents;
187 218
188 - if ( ! $kinds['smart'] ) {
189 - // if smart, we are not dumb so no need to check.
190 - $dumb_agents = $ua_info->dumb_agents;
219 + foreach ( $dumb_agents as $dumb_agent ) {
220 + if ( false !== strpos( $agent, $dumb_agent ) ) {
221 + $kinds['dumb'] = true;
222 + $matched_agent = $dumb_agent;
191 223
192 - foreach ( $dumb_agents as $dumb_agent ) {
193 - if ( false !== strpos( $agent, $dumb_agent ) ) {
194 - $kinds['dumb'] = true;
195 - $matched_agent = $dumb_agent;
196 -
197 - break;
198 - }
224 + break;
199 225 }
226 + }
200 227
201 - if ( ! $kinds['dumb'] ) {
202 - if ( isset( $_SERVER['HTTP_X_WAP_PROFILE'] ) ) {
203 - $kinds['dumb'] = true;
204 - $matched_agent = 'http_x_wap_profile';
205 - } elseif ( isset( $_SERVER['HTTP_ACCEPT'] ) && ( preg_match( '/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'] ) || false !== strpos( strtolower( $_SERVER['HTTP_ACCEPT'] ), 'application/vnd.wap.xhtml+xml' ) ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- This is doing the validating.
206 - $kinds['dumb'] = true;
207 - $matched_agent = 'vnd.wap.xhtml+xml';
208 - }
228 + if ( ! $kinds['dumb'] ) {
229 + if ( isset( $_SERVER['HTTP_X_WAP_PROFILE'] ) ) {
230 + $kinds['dumb'] = true;
231 + $matched_agent = 'http_x_wap_profile';
232 + } elseif ( isset( $_SERVER['HTTP_ACCEPT'] ) && ( preg_match( '/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'] ) || false !== strpos( strtolower( $_SERVER['HTTP_ACCEPT'] ), 'application/vnd.wap.xhtml+xml' ) ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- This is doing the validating.
233 + $kinds['dumb'] = true;
234 + $matched_agent = 'vnd.wap.xhtml+xml';
209 235 }
210 236 }
237 + }
211 238
212 - if ( $kinds['dumb'] || $kinds['smart'] ) {
213 - $kinds['any'] = true;
214 - }
239 + if ( $kinds['dumb'] || $kinds['smart'] ) {
240 + $kinds['any'] = true;
215 241 }
216 242
217 243 $value = $kinds[ $kind ];
218 244