From 0cd9feee572cce26d6f74f1f1dde174cf9a88d0d Mon Sep 17 00:00:00 2001
From: Guiu Rocafort <guiu.rocafort.ferrer@gmail.com>
Date: Thu, 30 Jan 2025 09:24:39 +0000
Subject: [PATCH 01/10] Issue #3301239 by @immaculate.x : Check if the file is
 correctly opened before trying to write the translation file contents to it.

---
 core/lib/Drupal/Component/Gettext/PoStreamReader.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/lib/Drupal/Component/Gettext/PoStreamReader.php b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
index 46a18498aee6..ad7c8597757e 100644
--- a/core/lib/Drupal/Component/Gettext/PoStreamReader.php
+++ b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
@@ -245,7 +245,7 @@ private function readHeader() {
   private function readLine() {
     // Read a line and set the stream finished indicator if it was not
     // possible anymore.
-    $line = fgets($this->fd);
+    $line = $this->fd ? fgets($this->fd) : FALSE;
     $this->finished = ($line === FALSE);
 
     if (!$this->finished) {
-- 
GitLab


From 4917f3d8bffbde9f8b2590e485abc0cc63be6b03 Mon Sep 17 00:00:00 2001
From: Guiu Rocafort <guiu.rocafort.ferrer@gmail.com>
Date: Tue, 4 Feb 2025 10:05:29 +0000
Subject: [PATCH 02/10] #3301239 Added test case to validate readItem returns
 NULL when the fd is not valid

---
 .../Component/Gettext/PoStreamReaderTest.php  | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php

diff --git a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
new file mode 100644
index 000000000000..040bb006f9c0
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\Component\Gettext;
+
+use Drupal\Component\Gettext\PoStreamReader;
+use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\TestStatus\Warning;
+
+/**
+ * Unit tests for the Gettext PO file header handling features.
+ *
+ * @see Drupal\Component\Gettext\PoHeader.
+ *
+ * @group Gettext
+ */
+class PoStreamreaderTest extends TestCase {
+
+  /**
+   * This test validates that calling readItem with a NULL fd
+   * returns NULL. See issue #3301239
+   *
+   */
+  public function testOpeningFileError() {
+    $reader = new PoStreamReader();
+    $reader->setURI('fake');
+    $this->assertNull($reader->readItem());
+  }
+
+}
-- 
GitLab


From 65c21a4fc56179f143fe8b1dfb5f8134be5d23a7 Mon Sep 17 00:00:00 2001
From: Guiu Rocafort <guiu.rocafort.ferrer@gmail.com>
Date: Tue, 4 Feb 2025 10:14:22 +0000
Subject: [PATCH 03/10] Fixed phpcs and phpstan issues

---
 .../Tests/Component/Gettext/PoStreamReaderTest.php       | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
index 040bb006f9c0..35d839c8b932 100644
--- a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
+++ b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
@@ -6,7 +6,6 @@
 
 use Drupal\Component\Gettext\PoStreamReader;
 use PHPUnit\Framework\TestCase;
-use PHPUnit\Framework\TestStatus\Warning;
 
 /**
  * Unit tests for the Gettext PO file header handling features.
@@ -15,14 +14,14 @@
  *
  * @group Gettext
  */
-class PoStreamreaderTest extends TestCase {
+class PoStreamReaderTest extends TestCase {
 
   /**
-   * This test validates that calling readItem with a NULL fd
-   * returns NULL. See issue #3301239
+   * Validates that calling readItem with a NULL fd returns NULL.
    *
+   * See issue #3301239.
    */
-  public function testOpeningFileError() {
+  public function testOpeningFileError(): void {
     $reader = new PoStreamReader();
     $reader->setURI('fake');
     $this->assertNull($reader->readItem());
-- 
GitLab


From 9f5c84231faa812195a55a1ed09d8478b5a5dcb6 Mon Sep 17 00:00:00 2001
From: Guiu Rocafort <guiu.rocafort.ferrer@gmail.com>
Date: Wed, 5 Feb 2025 10:55:05 +0000
Subject: [PATCH 04/10] #3301239 Throw an exception if the open method fails to
 open the uri.

---
 core/lib/Drupal/Component/Gettext/PoStreamReader.php | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/core/lib/Drupal/Component/Gettext/PoStreamReader.php b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
index ad7c8597757e..9cdd7a7c50c6 100644
--- a/core/lib/Drupal/Component/Gettext/PoStreamReader.php
+++ b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
@@ -150,13 +150,14 @@ public function setURI($uri) {
    *   If the URI is not yet set.
    */
   public function open() {
-    if (!empty($this->uri)) {
-      $this->fd = fopen($this->uri, 'rb');
-      $this->readHeader();
-    }
-    else {
+    if (empty($this->uri)) {
       throw new \Exception('Cannot open stream without URI set.');
     }
+    $this->fd = fopen($this->uri, 'rb');
+    if (!$this->fd) {
+      throw new \Exception('Cannot open stream');
+    }
+    $this->readHeader();
   }
 
   /**
-- 
GitLab


From 453561a1a1212aae0bc83186b3da68717b830b88 Mon Sep 17 00:00:00 2001
From: Guiu Rocafort <guiu.rocafort.ferrer@gmail.com>
Date: Wed, 5 Feb 2025 10:55:42 +0000
Subject: [PATCH 05/10] #3301239: Added a test to validate the open method
 throws an exception if the uri is invalid.

---
 .../Tests/Component/Gettext/PoStreamReaderTest.php    | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
index 35d839c8b932..8a55b672959c 100644
--- a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
+++ b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
@@ -16,6 +16,17 @@
  */
 class PoStreamReaderTest extends TestCase {
 
+  /**
+   * Calling open should throws an exception if URI is invalid .
+   *
+   */
+  public function testOpenMethodThrowsExceptionOnInvalidURI(): void {
+    $reader = new PoStreamReader();
+    $reader->setURI('fake');
+    $this->expectException(\Exception::class);
+    $reader->open();
+  }
+
   /**
    * Validates that calling readItem with a NULL fd returns NULL.
    *
-- 
GitLab


From 82fea54f5405f46cbddc83fc8ce5d22d1c09afcf Mon Sep 17 00:00:00 2001
From: Guiu Rocafort <guiu.rocafort.ferrer@gmail.com>
Date: Wed, 5 Feb 2025 10:58:53 +0000
Subject: [PATCH 06/10] Fix phpcs warning

---
 core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
index 8a55b672959c..d9b998925e87 100644
--- a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
+++ b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
@@ -19,6 +19,7 @@ class PoStreamReaderTest extends TestCase {
   /**
    * Calling open should throws an exception if URI is invalid .
    *
+   * See issue #3301239.
    */
   public function testOpenMethodThrowsExceptionOnInvalidURI(): void {
     $reader = new PoStreamReader();
-- 
GitLab


From 7db46e263a32758ee37b52262966641c8caf5c67 Mon Sep 17 00:00:00 2001
From: Pieter Frenssen <pieter@frenssen.be>
Date: Wed, 5 Feb 2025 15:45:27 +0200
Subject: [PATCH 07/10] We are doing our own error handling, suppress PHP
 warnings.

---
 core/lib/Drupal/Component/Gettext/PoStreamReader.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/lib/Drupal/Component/Gettext/PoStreamReader.php b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
index 9cdd7a7c50c6..14e15a1c9c25 100644
--- a/core/lib/Drupal/Component/Gettext/PoStreamReader.php
+++ b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
@@ -153,7 +153,7 @@ public function open() {
     if (empty($this->uri)) {
       throw new \Exception('Cannot open stream without URI set.');
     }
-    $this->fd = fopen($this->uri, 'rb');
+    $this->fd = @fopen($this->uri, 'rb');
     if (!$this->fd) {
       throw new \Exception('Cannot open stream');
     }
-- 
GitLab


From 59869aa4ada30aac3f510d4fb1ac347a5bbdf7be Mon Sep 17 00:00:00 2001
From: Vladimir Roudakov <44088-VladimirAus@users.noreply.drupalcode.org>
Date: Thu, 6 Feb 2025 12:21:30 +0000
Subject: [PATCH 08/10] Issue #3301239 by iperiba92, immaculatexavier, i-grou,
 vladimiraus: Improve the error message thrown in PoStreamReader::readLine()
 when translations cannot be saved

---
 .../Component/Gettext/PoStreamReaderTest.php  | 24 +++++++++++++------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
index d9b998925e87..3ca35a62dee7 100644
--- a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
+++ b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
@@ -17,25 +17,35 @@
 class PoStreamReaderTest extends TestCase {
 
   /**
-   * Calling open should throws an exception if URI is invalid .
+   * Creates and returns a PoStreamReader instance with a fake URI.
    *
-   * See issue #3301239.
+   * @return \Drupal\Component\Gettext\PoStreamReader
+   *   The PoStreamReader instance.
    */
-  public function testOpenMethodThrowsExceptionOnInvalidURI(): void {
+  private function createPoStreamReader(): PoStreamReader {
     $reader = new PoStreamReader();
     $reader->setURI('fake');
-    $this->expectException(\Exception::class);
+    return $reader;
+  }
+
+  /**
+   * Calling open should throw an exception if URI is invalid.
+   *
+   * See issue #3301239.
+   */
+  public function testOpenMethodThrowsExceptionOnInvalidURI(): void {
+    $reader = $this->createPoStreamReader();
+    $this->expectException(Exception::class);
     $reader->open();
   }
 
   /**
-   * Validates that calling readItem with a NULL fd returns NULL.
+   * Validates that calling readItem with a NULL file descriptor returns NULL.
    *
    * See issue #3301239.
    */
   public function testOpeningFileError(): void {
-    $reader = new PoStreamReader();
-    $reader->setURI('fake');
+    $reader = $this->createPoStreamReader();
     $this->assertNull($reader->readItem());
   }
 
-- 
GitLab


From 99696c72ae664b11b7e3134f4f898e2406b6f37e Mon Sep 17 00:00:00 2001
From: Guiu Rocafort <guiu.rocafort.ferrer@gmail.com>
Date: Fri, 7 Feb 2025 20:57:13 +0000
Subject: [PATCH 09/10] Fix phpstan error.

---
 .../tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
index 3ca35a62dee7..5d74f1f3801d 100644
--- a/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
+++ b/core/tests/Drupal/Tests/Component/Gettext/PoStreamReaderTest.php
@@ -35,7 +35,7 @@ private function createPoStreamReader(): PoStreamReader {
    */
   public function testOpenMethodThrowsExceptionOnInvalidURI(): void {
     $reader = $this->createPoStreamReader();
-    $this->expectException(Exception::class);
+    $this->expectException(\Exception::class);
     $reader->open();
   }
 
-- 
GitLab


From c6721a58ece60617f806f9928b84b8c281b51786 Mon Sep 17 00:00:00 2001
From: Hristo Chonov <h.chonov@1xinternet.de>
Date: Thu, 13 Mar 2025 16:49:14 +0200
Subject: [PATCH 10/10] Add uri to exception message

---
 core/lib/Drupal/Component/Gettext/PoStreamReader.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/lib/Drupal/Component/Gettext/PoStreamReader.php b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
index 14e15a1c9c25..875abc86190a 100644
--- a/core/lib/Drupal/Component/Gettext/PoStreamReader.php
+++ b/core/lib/Drupal/Component/Gettext/PoStreamReader.php
@@ -155,7 +155,7 @@ public function open() {
     }
     $this->fd = @fopen($this->uri, 'rb');
     if (!$this->fd) {
-      throw new \Exception('Cannot open stream');
+      throw new \Exception('Cannot open stream for uri ' . $this->uri);
     }
     $this->readHeader();
   }
-- 
GitLab