Skip to content

Commit e0cb5c5

Browse files
author
Hai Zheng
committed
cx 🐞 修复审查发现的失败路径
1 parent 93fb5d2 commit e0cb5c5

8 files changed

Lines changed: 137 additions & 24 deletions

File tree

changelog.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
= 8.0 - Coming soon 2026 =
2+
* 🌱**OptiMax** OptiMax to maximize the page score.
3+
* **Core** Aligned the runtime PHP and WordPress guards with the published minimum requirements.
4+
* 🐞**Image Optimize** Fixed a fatal error when the WordPress HTTP fallback could not download an image.
5+
* 🐞**Avatar** Prevented failed on-demand avatar downloads from redirecting visitors to the WordPress admin area.
6+
17
= 7.7 - Dec 16 2025 =
28
* **Task** Increased default cron interval from 1 minute to 15 minutes.
39
* **Conf** Enabled `litespeed_conf_load_option_{$option}` to allow modifying configuration values.

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
},
1212
"prefer-stable": true,
1313
"scripts": {
14-
"sniff-check": "vendor/bin/phpcs --standard=phpcs.ruleset.xml --no-cache cli/ lib/ src/ tpl/ thirdparty autoload.php litespeed-cache.php"
14+
"sniff-check": "vendor/bin/phpcs --standard=phpcs.ruleset.xml --no-cache cli/ lib/ src/ tpl/ thirdparty tests autoload.php litespeed-cache.php",
15+
"test-regression": "php tests/regression/img-optm-pull-wp-error.php"
1516
},
1617
"config": {
1718
"allow-plugins": {

litespeed-cache.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,13 @@ function wp_nonce_tick_litespeed_esi( $action = -1 ) {
224224
* @since 1.0.0
225225
*/
226226
function run_litespeed_cache() {
227-
// Check minimum PHP requirements, which is 7.2 at the moment.
228-
if ( version_compare( PHP_VERSION, '7.2.0', '<' ) ) {
227+
// Check minimum PHP requirements, which is 7.4 at the moment.
228+
if ( version_compare( PHP_VERSION, '7.4.0', '<' ) ) {
229229
return;
230230
}
231231

232-
// Check minimum WP requirements, which is 5.3 at the moment.
233-
if ( version_compare( $GLOBALS['wp_version'], '5.3', '<' ) ) {
232+
// Check minimum WP requirements, which is 6.0 at the moment.
233+
if ( version_compare( $GLOBALS['wp_version'], '6.0', '<' ) ) {
234234
return;
235235
}
236236

readme.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ You can report security bugs through the Patchstack Vulnerability Disclosure Pro
259259

260260
= 8.0 - Coming soon 2026 =
261261
* 🌱**OptiMax** OptiMax to maximize the page score.
262+
* **Core** Aligned the runtime PHP and WordPress guards with the published minimum requirements.
263+
* 🐞**Image Optimize** Fixed a fatal error when the WordPress HTTP fallback could not download an image.
264+
* 🐞**Avatar** Prevented failed on-demand avatar downloads from redirecting visitors to the WordPress admin area.
262265

263266
= 7.9 - Aug 5 2026 =
264267
* **Cloud** Changed Health service to run asynchronously, resuming through WP cron when the cloud defers the request.

src/avatar.cls.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,13 @@ public function serve_static( $md5 ) {
110110
return;
111111
}
112112

113-
$url = $this->_generate( $url );
113+
$generated_url = $this->_generate( $url );
114+
if ( $generated_url === $url ) {
115+
self::debug( '[Avatar] generation failed; bypassing redirect' );
116+
return;
117+
}
114118

115-
wp_safe_redirect( $url );
119+
wp_safe_redirect( $generated_url );
116120
exit;
117121
}
118122

src/img-optm-pull.trait.php

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,33 @@ private function _calc_pull_threads() {
275275
return $imgs_per_req;
276276
}
277277

278+
/**
279+
* Normalize a WordPress HTTP response for the shared pull completion callback.
280+
*
281+
* @param array|\WP_Error $wp_response WordPress HTTP response.
282+
* @param string $url Requested URL for diagnostics.
283+
* @return object
284+
*/
285+
private function _parse_wp_pull_response( $wp_response, $url ) {
286+
$request_response = [
287+
'success' => false,
288+
'status_code' => 0,
289+
'body' => null,
290+
'sslverify' => false,
291+
];
292+
293+
if ( is_wp_error( $wp_response ) ) {
294+
self::debug( '❌ failed to pull image: ' . $wp_response->get_error_message() );
295+
} else {
296+
$request_response['success'] = true;
297+
$request_response['status_code'] = $wp_response['response']['code'];
298+
$request_response['body'] = $wp_response['body'];
299+
self::debug( 'response code [code] ' . $wp_response['response']['code'] . ' [url] ' . $url );
300+
}
301+
302+
return (object) $request_response;
303+
}
304+
278305
/**
279306
* Pull optimized img
280307
*
@@ -552,23 +579,7 @@ public function pull( $manual = false ) {
552579
} else {
553580
foreach ( $requests as $cnt => $req ) {
554581
$wp_response = wp_safe_remote_get( $req['url'], [ 'timeout' => 60 ] );
555-
$request_response = [
556-
'success' => false,
557-
'status_code' => 0,
558-
'body' => null,
559-
'sslverify' => false,
560-
];
561-
if ( is_wp_error( $wp_response ) ) {
562-
$error_message = $wp_response->get_error_message();
563-
self::debug( '❌ failed to pull image: ' . $error_message );
564-
} else {
565-
$request_response['success'] = true;
566-
$request_response['status_code'] = $wp_response['response']['code'];
567-
$request_response['body'] = $wp_response['body'];
568-
}
569-
self::debug( 'response code [code] ' . $wp_response['response']['code'] . ' [url] ' . $req['url'] );
570-
571-
$request_response = (object) $request_response;
582+
$request_response = $this->_parse_wp_pull_response( $wp_response, $req['url'] );
572583

573584
$complete_action( $request_response, $cnt );
574585
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Regression test for the image pull WordPress HTTP fallback.
4+
*
5+
* @package LiteSpeed
6+
*/
7+
8+
namespace LiteSpeed;
9+
10+
define( 'WPINC', 'regression-test' );
11+
12+
require __DIR__ . '/wp-error-stub.php';
13+
require dirname( __DIR__, 2 ) . '/src/img-optm-pull.trait.php';
14+
15+
/**
16+
* Expose the response normalizer without loading WordPress.
17+
*/
18+
final class Img_Optm_Pull_Harness {
19+
use Img_Optm_Pull;
20+
21+
/**
22+
* Discard debug output during the regression test.
23+
*
24+
* @param string $message Debug message.
25+
* @return void
26+
*/
27+
public static function debug( $message ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
28+
}
29+
30+
/**
31+
* Normalize a simulated HTTP response.
32+
*
33+
* @param mixed $response Simulated response.
34+
* @param string $url Requested URL.
35+
* @return object
36+
*/
37+
public function parse( $response, $url ) {
38+
return $this->_parse_wp_pull_response( $response, $url );
39+
}
40+
}
41+
42+
$test_error = new class() {
43+
/**
44+
* Return the simulated network error.
45+
*
46+
* @return string
47+
*/
48+
public function get_error_message() {
49+
return 'simulated network failure';
50+
}
51+
};
52+
53+
$harness = new Img_Optm_Pull_Harness();
54+
$result = $harness->parse( $test_error, 'https://example.test/image.jpg' );
55+
56+
if ( false !== $result->success || 0 !== $result->status_code || null !== $result->body ) {
57+
throw new \RuntimeException( 'WP_Error responses must remain failed without array access.' );
58+
}
59+
60+
$result = $harness->parse(
61+
[
62+
'response' => [ 'code' => 200 ],
63+
'body' => 'image-data',
64+
],
65+
'https://example.test/image.jpg'
66+
);
67+
68+
if ( true !== $result->success || 200 !== $result->status_code || 'image-data' !== $result->body ) {
69+
throw new \RuntimeException( 'Successful WordPress HTTP responses must retain status and body.' );
70+
}
71+
72+
echo "img-optm WP_Error regression: ok\n";

tests/regression/wp-error-stub.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* Minimal WordPress error helper for regression tests.
4+
*
5+
* @package LiteSpeed
6+
*/
7+
8+
/**
9+
* Identify the anonymous WP_Error test double.
10+
*
11+
* @param mixed $value Candidate response.
12+
* @return bool
13+
*/
14+
function is_wp_error( $value ) {
15+
return is_object( $value ) && method_exists( $value, 'get_error_message' );
16+
}

0 commit comments

Comments
 (0)