From 43d56edb35b193b194945337ecfeaa2625e6125c Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Tue, 12 Aug 2025 11:21:49 +0200 Subject: [PATCH 01/14] image validation --- src/Store/ImageSaver.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Store/ImageSaver.php b/src/Store/ImageSaver.php index 5f1915e..c770cfd 100644 --- a/src/Store/ImageSaver.php +++ b/src/Store/ImageSaver.php @@ -43,6 +43,16 @@ public function save( $data ): ?string { $data = str_replace( ' ', '+', $data ); $data = base64_decode($data); + try { + $image = imagecreatefromstring( $data ); + } catch ( \Exception $e ) { + return null; + } + + if ( $image === false ) { + return null; + } + if ( $data === false ) { return null; } From 32b698a9a8f57f68c69798b24ca2f03ba084ad78 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Tue, 12 Aug 2025 11:51:22 +0200 Subject: [PATCH 02/14] vbump --- extension.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension.json b/extension.json index e87b215..12afbf4 100644 --- a/extension.json +++ b/extension.json @@ -6,7 +6,7 @@ "Robin van der Wiel", "Yvar Nanlohij" ], - "version": "2.1.1", + "version": "2.1.2", "url": "https://www.archixl.nl", "descriptionmsg": "sic-desc", "license-name": "GPL-2.0+", From 0e89c8ebc427f84f4d313f17ed7e65ccbdcc1e55 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 13:49:28 +0200 Subject: [PATCH 03/14] add test and use full title of page to show on special page --- src/DBHandler.php | 2 +- .../Integration/Store/ImageSaverTest.php | 88 +++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/Integration/Store/ImageSaverTest.php diff --git a/src/DBHandler.php b/src/DBHandler.php index 6606757..4a5628f 100644 --- a/src/DBHandler.php +++ b/src/DBHandler.php @@ -385,7 +385,7 @@ public static function selectAllPages() : array { foreach ( $res as $page ) { $title = Title::newFromID( $page ); if ( $title ) { - $pages[] = $title->getText(); + $pages[] = $title->getFullText(); } } diff --git a/tests/phpunit/Integration/Store/ImageSaverTest.php b/tests/phpunit/Integration/Store/ImageSaverTest.php new file mode 100644 index 0000000..e67c1fb --- /dev/null +++ b/tests/phpunit/Integration/Store/ImageSaverTest.php @@ -0,0 +1,88 @@ +titleMock = $this->createMock( \Title::class ); + $this->titleMock->method( 'getId' )->willReturn( 123 ); + + Hooks::$imageSaveDirectory = sys_get_temp_dir(); + } + + /** + * Test that ImageSaver returns null for invalid XSS payload + */ + public function testInvalidXssPayload(): void { + $imageSaver = new ImageSaver( $this->titleMock ); + + $invalidPayload = 'data:image/png;base64,PHNjcmlwdD5hbGVydCgneHNzJyk7PC9zY3JpcHQ+'; + + $result = $imageSaver->save( $invalidPayload ); + + $this->assertNull( $result, 'ImageSaver should return null for XSS payload' ); + } + + /** + * Test that ImageSaver returns a filename for valid payload + */ + public function testValidPayload(): void { + $imageSaver = new ImageSaver( $this->titleMock ); + + $validPayload = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; + + $result = $imageSaver->save( $validPayload ); + + $this->assertNotNull( $result, 'ImageSaver should return a filename for valid payload' ); + + $filePath = Hooks::$imageSaveDirectory . '/' . $result; + $this->assertFileExists( $filePath, 'Image file should be created' ); + + if ( file_exists( $filePath ) ) { + unlink( $filePath ); + } + } + + /** + * Test that ImageSaver returns null for non-image data + */ + public function testNonImageData(): void { + $imageSaver = new ImageSaver( $this->titleMock ); + + // Base64 encoded text that's not an image + $nonImagePayload = 'data:image/png;base64,SGVsbG8gV29ybGQ='; + + $result = $imageSaver->save( $nonImagePayload ); + + // Assert that the result is null for non-image data + $this->assertNull( $result, 'ImageSaver should return null for non-image data' ); + } + + /** + * Test that ImageSaver returns null for unsupported image type + */ + public function testUnsupportedImageType(): void { + $imageSaver = new ImageSaver( $this->titleMock ); + + $unsupportedTypePayload = 'data:image/webp;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; + + $result = $imageSaver->save( $unsupportedTypePayload ); + + $this->assertNull( $result, 'ImageSaver should return null for unsupported image type' ); + } +} \ No newline at end of file From c902c857c96667c8361c620979c9148206808d3d Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:17:43 +0200 Subject: [PATCH 04/14] fix smw version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4be1fa2..ccdd4b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: matrix: include: - mediawiki_version: '1.39' - smw_version: dev-master + smw_version: '5.1.0' php_version: 8.1 database_type: mysql database_image: "mariadb:10" From 2207df39e97ea1a62c88078343d9cf082759d120 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:22:49 +0200 Subject: [PATCH 05/14] try and fix test --- src/Store/ImageSaver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Store/ImageSaver.php b/src/Store/ImageSaver.php index c770cfd..ce47757 100644 --- a/src/Store/ImageSaver.php +++ b/src/Store/ImageSaver.php @@ -44,7 +44,7 @@ public function save( $data ): ?string { $data = base64_decode($data); try { - $image = imagecreatefromstring( $data ); + $image = \imagecreatefromstring( $data ); } catch ( \Exception $e ) { return null; } From 941a2dbb9a128646cc5a9f64ff91045378df3377 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:45:33 +0200 Subject: [PATCH 06/14] try and install gd --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccdd4b2..f390241 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,12 +24,14 @@ jobs: database_image: "mariadb:10" coverage: false experimental: true + php_extensions: "gd" env: MW_VERSION: ${{ matrix.mediawiki_version }} SMW_VERSION: ${{ matrix.smw_version }} PHP_VERSION: ${{ matrix.php_version }} DB_TYPE: ${{ matrix.database_type }} DB_IMAGE: ${{ matrix.database_image }} + PHP_EXTENSIONS: ${{ matrix.php_extensions }} steps: From 7b36bfc8baaa235cf47f4594329568a338ce6888 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:50:57 +0200 Subject: [PATCH 07/14] try and fix text --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f390241..2580060 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: database_image: "mariadb:10" coverage: false experimental: true - php_extensions: "gd" + php_extensions: gd env: MW_VERSION: ${{ matrix.mediawiki_version }} SMW_VERSION: ${{ matrix.smw_version }} From ee43dc5c7a21c0984d7b514b694c08ef00722da0 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:52:52 +0200 Subject: [PATCH 08/14] add zlib --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2580060..8e94ff4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,9 @@ jobs: database_image: "mariadb:10" coverage: false experimental: true - php_extensions: gd + php_extensions: + - gd + - zlib env: MW_VERSION: ${{ matrix.mediawiki_version }} SMW_VERSION: ${{ matrix.smw_version }} From d0059b32601fd09173b555d2d1c9e181dc28bbb0 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:56:00 +0200 Subject: [PATCH 09/14] fix invalid yml --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e94ff4..ed0c237 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,9 +24,7 @@ jobs: database_image: "mariadb:10" coverage: false experimental: true - php_extensions: - - gd - - zlib + php_extensions: [ gd, zlib ] env: MW_VERSION: ${{ matrix.mediawiki_version }} SMW_VERSION: ${{ matrix.smw_version }} From f2562446cde816fed0a576ffd1107884c6dcdeca Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:57:25 +0200 Subject: [PATCH 10/14] fix yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed0c237..1ab6b32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: database_image: "mariadb:10" coverage: false experimental: true - php_extensions: [ gd, zlib ] + php_extensions: "gd, zlib" env: MW_VERSION: ${{ matrix.mediawiki_version }} SMW_VERSION: ${{ matrix.smw_version }} From 161a0ce85d95605d9c6fa3dda5263a354813c3d4 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 15:59:51 +0200 Subject: [PATCH 11/14] remove zlib --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ab6b32..f390241 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: database_image: "mariadb:10" coverage: false experimental: true - php_extensions: "gd, zlib" + php_extensions: "gd" env: MW_VERSION: ${{ matrix.mediawiki_version }} SMW_VERSION: ${{ matrix.smw_version }} From ae3e9d9b8d75a933ffff0e04aeac0b8c9b1caa52 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 16:04:55 +0200 Subject: [PATCH 12/14] use make instead --- .github/workflows/ci.yml | 2 -- Makefile | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f390241..ccdd4b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,14 +24,12 @@ jobs: database_image: "mariadb:10" coverage: false experimental: true - php_extensions: "gd" env: MW_VERSION: ${{ matrix.mediawiki_version }} SMW_VERSION: ${{ matrix.smw_version }} PHP_VERSION: ${{ matrix.php_version }} DB_TYPE: ${{ matrix.database_type }} DB_IMAGE: ${{ matrix.database_image }} - PHP_EXTENSIONS: ${{ matrix.php_extensions }} steps: diff --git a/Makefile b/Makefile index d824fc2..7b59613 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,9 @@ DB_IMAGE?="" SMW_VERSION?=4.1.3 MM_VERSION ?= 3.1.0 +# PHP extensions +PHP_EXTENSIONS?=gd zlib + # composer # Enables "composer update" inside of extension COMPOSER_EXT?=true From 8e129977993929752bf61734b0c40ed210d8bce9 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Wed, 13 Aug 2025 16:07:21 +0200 Subject: [PATCH 13/14] use comma seperated --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7b59613..d2e046a 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ SMW_VERSION?=4.1.3 MM_VERSION ?= 3.1.0 # PHP extensions -PHP_EXTENSIONS?=gd zlib +PHP_EXTENSIONS?=gd,zlib # composer # Enables "composer update" inside of extension From 082059f527251a2064b8104a398fb6d4a0f8ce31 Mon Sep 17 00:00:00 2001 From: YvarRavy Date: Thu, 14 Aug 2025 09:22:04 +0200 Subject: [PATCH 14/14] changes to i18n --- i18n/nl.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/i18n/nl.json b/i18n/nl.json index 88fb684..339ece3 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -124,6 +124,7 @@ "sic-selection-generic-error": "Er is een fout opgetreden tijdens tekst selectie.", "sic-show-screenshot-full-size": "Klik om de volledige grootte te bekijken", "sic-broken-comments-below": "Er zijn opmerkingen die niet meer gekoppeld zijn aan een tekstselectie op deze pagina", - "sc-status-open": "Open", - "sc-status-completed": "Afgesloten" -} \ No newline at end of file + "sc-status-open": "open", + "sc-status-completed": "afgehandeld" +} +