From cce40907d5dfdee04520d5e94f771c2de3af12a1 Mon Sep 17 00:00:00 2001
From: Keith Solomon
Date: Sun, 26 Apr 2026 20:45:18 -0500
Subject: [PATCH] fix: handle invalid package uploads
---
src/Admin/FileImportController.php | 31 +++++++++++++-
templates/admin/dashboard.php | 14 +++++++
tests/Unit/Admin/DashboardTemplateTest.php | 41 +++++++++++++++++++
tests/Unit/Admin/FileImportControllerTest.php | 14 +++++++
4 files changed, 98 insertions(+), 2 deletions(-)
create mode 100644 tests/Unit/Admin/DashboardTemplateTest.php
diff --git a/src/Admin/FileImportController.php b/src/Admin/FileImportController.php
index 5f36908..bd93a24 100644
--- a/src/Admin/FileImportController.php
+++ b/src/Admin/FileImportController.php
@@ -49,7 +49,23 @@ final class FileImportController {
throw new \RuntimeException( 'The package file could not be read.' );
}
- $package = $this->transport->import( $contents );
+ try {
+ $package = $this->transport->import( $contents );
+ } catch ( \InvalidArgumentException $exception ) {
+ $this->logger->warning(
+ 'Rejected imported content package.',
+ array(
+ 'error' => $exception->getMessage(),
+ )
+ );
+
+ $this->redirectToDashboard(
+ array(
+ 'wpcs_import_error' => $exception->getMessage(),
+ )
+ );
+ return;
+ }
$this->logger->info(
'Validated imported content package.',
@@ -59,9 +75,20 @@ final class FileImportController {
)
);
+ $this->redirectToDashboard(
+ array(
+ 'wpcs_imported' => '1',
+ )
+ );
+ }
+
+ /**
+ * @param array $args Redirect query args.
+ */
+ private function redirectToDashboard( array $args ): void {
wp_safe_redirect(
add_query_arg(
- array( 'wpcs_imported' => '1' ),
+ $args,
admin_url( 'admin.php?page=wp-content-sync' )
)
);
diff --git a/templates/admin/dashboard.php b/templates/admin/dashboard.php
index e066fa6..c59eddd 100644
--- a/templates/admin/dashboard.php
+++ b/templates/admin/dashboard.php
@@ -26,6 +26,20 @@ if ( ! defined( 'ABSPATH' ) ) {
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Unit/Admin/DashboardTemplateTest.php b/tests/Unit/Admin/DashboardTemplateTest.php
new file mode 100644
index 0000000..8681013
--- /dev/null
+++ b/tests/Unit/Admin/DashboardTemplateTest.php
@@ -0,0 +1,41 @@
+renderDashboard();
+
+ self::assertStringContainsString( 'notice-error', $output );
+ self::assertStringContainsString( 'The selected file is not valid JSON.', $output );
+ }
+
+ public function test_it_renders_import_success_notices(): void {
+ $_GET['wpcs_imported'] = '1';
+
+ $output = $this->renderDashboard();
+
+ self::assertStringContainsString( 'notice-success', $output );
+ self::assertStringContainsString( 'The package JSON file was validated successfully.', $output );
+ }
+
+ private function renderDashboard(): string {
+ $settings = Settings::fromArray( array() );
+
+ ob_start();
+ include WPCS_PLUGIN_DIR . 'templates/admin/dashboard.php';
+
+ return (string) ob_get_clean();
+ }
+}
diff --git a/tests/Unit/Admin/FileImportControllerTest.php b/tests/Unit/Admin/FileImportControllerTest.php
index f1e962e..8e7898c 100644
--- a/tests/Unit/Admin/FileImportControllerTest.php
+++ b/tests/Unit/Admin/FileImportControllerTest.php
@@ -82,6 +82,20 @@ class FileImportControllerTest extends TestCase {
self::assertStringContainsString( 'wpcs_imported=1', $GLOBALS['wpcs_redirect_location'] );
}
+ public function test_it_redirects_with_error_for_invalid_uploaded_packages(): void {
+ $file = $this->createTemporaryPackageFile( '{"schema_version":' );
+
+ $_FILES['wpcs_package_file'] = array(
+ 'tmp_name' => $file,
+ 'error' => UPLOAD_ERR_OK,
+ );
+
+ $this->controller()->handleImport();
+
+ self::assertStringContainsString( 'wpcs_import_error=', $GLOBALS['wpcs_redirect_location'] );
+ self::assertStringContainsString( 'not+valid+JSON', $GLOBALS['wpcs_redirect_location'] );
+ }
+
private function controller(): FileImportController {
return new FileImportController(
new JsonFileTransport( new PackageValidator() ),