Explorar o código

Fix LibOPML warnings (#8652)

* Fix LibOPML warnings
Fix https://github.com/FreshRSS/FreshRSS/issues/8651
Apply the same flags than in other similar calls of FreshRSS
Will need to send the patch upstream.

* No LIBXML_NOERROR due to unit tests expecting a catch

* LIBXML_NOERROR while waiting for better upstream fix

* lib_opml fix loadXML warnings
fix https://github.com/FreshRSS/FreshRSS/issues/8651
Upstream PR https://framagit.org/marienfressinaud/lib_opml/-/merge_requests/48

* Fix regression
https://framagit.org/marienfressinaud/lib_opml/-/merge_requests/51

* Temporarily use fork
Alexandre Alapetite hai 5 días
pai
achega
1ac1d8c2eb

+ 4 - 0
lib/.gitignore

@@ -1,14 +1,17 @@
 autoload.php
 composer.lock
 composer/
+
 marienfressinaud/lib_opml/.git/
 marienfressinaud/lib_opml/.gitlab-ci.yml
 marienfressinaud/lib_opml/.gitlab/
+marienfressinaud/lib_opml/.phpunit.xml
 marienfressinaud/lib_opml/ci/
 marienfressinaud/lib_opml/examples/
 marienfressinaud/lib_opml/Makefile
 marienfressinaud/lib_opml/src/functions.php
 marienfressinaud/lib_opml/tests/
+
 phpgt/cssxpath/.*
 phpgt/cssxpath/composer.json
 phpgt/cssxpath/CONTRIBUTING.md
@@ -24,6 +27,7 @@ phpmailer/phpmailer/SECURITY*
 phpmailer/phpmailer/src/DSNConfigurator.php
 phpmailer/phpmailer/src/OAuth*
 phpmailer/phpmailer/src/POP3.php
+
 simplepie/simplepie/.*
 !simplepie/simplepie/.editorconfig
 !simplepie/simplepie/.github/README.md

+ 5 - 1
lib/composer.json

@@ -8,10 +8,14 @@
 		{
 			"type": "git",
 			"url": "https://github.com/FreshRSS/simplepie.git"
+		},
+		{
+			"type": "git",
+			"url": "https://framagit.org/Alkarex/lib_opml.git"
 		}
 	],
 	"require": {
-		"marienfressinaud/lib_opml": "0.5.1",
+		"marienfressinaud/lib_opml": "dev-relax-non-fatal-errors#f0e850b6394af90b898daf0e65fcc7363457b844",
 		"phpgt/cssxpath": "v1.5.0",
 		"phpmailer/phpmailer": "7.0.2",
 		"simplepie/simplepie": "dev-freshrss#33e4bcf5685192b0fa4c9819f0813b47c3d22424"

+ 1 - 0
lib/marienfressinaud/lib_opml/.gitignore

@@ -1,2 +1,3 @@
 /coverage
 /vendor
+/.phpunit-cache

+ 12 - 0
lib/marienfressinaud/lib_opml/.phpcs.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHP_CodeSniffer" xsi:noNamespaceSchemaLocation="phpcs.xsd">
+    <description>The coding standard for lib_opml.</description>
+
+    <file>examples</file>
+    <file>src</file>
+    <file>tests</file>
+
+    <arg name="extensions" value="php" />
+
+    <rule ref="PSR12" />
+</ruleset>

+ 1 - 1
lib/marienfressinaud/lib_opml/README.md

@@ -7,7 +7,7 @@ structure arranged to show hierarchical relationships). It is mainly used to
 exchange list of feeds between feed aggregators. The specification is
 available at [opml.org](http://opml.org).
 
-lib\_opml has been tested with PHP 7.2+. It requires [DOMDocument](https://www.php.net/manual/book.dom.php)
+lib\_opml has been tested with PHP 8.2+. It requires [DOMDocument](https://www.php.net/manual/book.dom.php)
 to work.
 
 It supports versions 1.0 and 2.0 of OPML since these are the only published

+ 4 - 4
lib/marienfressinaud/lib_opml/composer.json

@@ -9,12 +9,12 @@
         }
     ],
     "require": {
-        "php": ">=7.2.0",
+        "php": ">=8.2",
         "ext-dom": "*"
     },
     "config": {
         "platform": {
-            "php": "7.2.0"
+            "php": "8.2"
         }
     },
     "support": {
@@ -29,7 +29,7 @@
         }
     },
     "require-dev": {
-        "squizlabs/php_codesniffer": "^3.6",
-        "phpunit/phpunit": "^8"
+        "squizlabs/php_codesniffer": "^4.0",
+        "phpunit/phpunit": "^11.0"
     }
 }

+ 38 - 3
lib/marienfressinaud/lib_opml/src/LibOpml/LibOpml.php

@@ -143,18 +143,30 @@ class LibOpml
      */
     public function parseString($xml)
     {
+        $xml = trim($xml);
+
+        if (!$xml) {
+            throw new Exception('OPML string cannot be empty');
+        }
+
         $dom = new \DOMDocument();
         $dom->recover = true;
         $dom->encoding = 'UTF-8';
 
+        libxml_use_internal_errors(true);
+
         try {
-            $result = @$dom->loadXML($xml);
+            $result = $dom->loadXML($xml, LIBXML_NONET | LIBXML_NOWARNING);
+            $error = $this->getLibxmlError();
         } catch (\Exception | \Error $e) {
             $result = false;
+            $error = $e->getMessage();
         }
 
-        if (!$result || !$dom->documentElement) {
-            throw new Exception('OPML string is not valid XML');
+        libxml_use_internal_errors(false);
+
+        if ($error) {
+            throw new Exception($error);
         }
 
         $opml_element = $dom->documentElement;
@@ -767,4 +779,27 @@ class LibOpml
             throw new Exception($message);
         }
     }
+
+    /**
+     * Return a formatted error if any libxml error is returned by
+     * libxml_get_errors(). In non-strict mode, only fatal errors are reported.
+     */
+    private function getLibxmlError(): string
+    {
+        $libxml_error = '';
+        $errors = libxml_get_errors();
+
+        foreach ($errors as $error) {
+            if (!$this->strict && $error->level < LIBXML_ERR_FATAL) {
+                continue;
+            }
+
+            $message = trim($error->message);
+            $message .= " (line {$error->line}, column {$error->column}, code {$error->code})";
+
+            $libxml_error .= $message . "\n";
+        }
+
+        return trim($libxml_error);
+    }
 }