jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1324317?usp=email )

Change subject: reflinks: Pass PDF bytes directly to pdfinfo
......................................................................

reflinks: Pass PDF bytes directly to pdfinfo

PDF responses are decoded as text before being written to a temporary
stream positioned at EOF. This can corrupt binary data and prevent
pdfinfo from extracting document metadata.

Pass the original response bytes through the documented pdfinfo stdin
interface and remove the temporary-file lifecycle. Add a regression test
for byte preservation and title parsing.

Change-Id: I3d95a9e3eeefad76e60e6d4f2231feca599fa4f4
---
M scripts/reflinks.py
M tests/reflinks_tests.py
2 files changed, 32 insertions(+), 16 deletions(-)

Approvals:
  jenkins-bot: Verified
  Xqt: Looks good to me, approved




diff --git a/scripts/reflinks.py b/scripts/reflinks.py
index 47721cd..3927a2b 100755
--- a/scripts/reflinks.py
+++ b/scripts/reflinks.py
@@ -53,10 +53,8 @@

 import http.client as httplib
 import itertools
-import os
 import re
 import subprocess
-import tempfile
 from contextlib import suppress
 from enum import IntEnum
 from functools import partial
@@ -498,18 +496,14 @@
     @staticmethod
     def getPDFTitle(ref, response) -> None:
         """Use pdfinfo to retrieve title from a PDF."""
-        # pdfinfo is Unix-only
         pywikibot.info('Reading PDF file...')
-        infile = None
         try:
-            fd, infile = tempfile.mkstemp()
-            urlobj = os.fdopen(fd, 'w+')
-            urlobj.write(response.text)
-            pdfinfo_out = subprocess.Popen([r'pdfinfo', '/dev/stdin'],
-                                           stdin=urlobj,
-                                           stdout=subprocess.PIPE,
-                                           stderr=subprocess.PIPE,
-                                           shell=False).communicate()[0]
+            pdfinfo_out = subprocess.run(
+                ['pdfinfo', '-'],
+                input=response.content,
+                capture_output=True,
+                check=False,
+            ).stdout
         except ValueError:
             pywikibot.info('pdfinfo value error.')
         except OSError:
@@ -527,10 +521,6 @@
                         pywikibot.info('title: ' + ref.title)
                         break
             pywikibot.info('PDF done.')
-        finally:
-            if infile is not None:
-                urlobj.close()
-                os.unlink(infile)

     def setup(self) -> None:
         """Read dead links from file."""
diff --git a/tests/reflinks_tests.py b/tests/reflinks_tests.py
index c75d103..6864723 100755
--- a/tests/reflinks_tests.py
+++ b/tests/reflinks_tests.py
@@ -8,6 +8,8 @@
 from __future__ import annotations

 import unittest
+from types import SimpleNamespace
+from unittest.mock import patch

 from scripts.reflinks import ReferencesRobot, XmlDumpPageGenerator, main
 from tests import join_xml_data_path
@@ -15,6 +17,30 @@
 from tests.utils import empty_sites


+class TestPDFTitle(TestCase):
+
+    """Tests for PDF title extraction."""
+
+    net = False
+
+    def test_pdf_bytes_passed_to_pdfinfo(self) -> None:
+        """Test that pdfinfo receives the unchanged PDF content."""
+        content = b'%PDF-1.7\x00\xff'
+        process = SimpleNamespace(
+            stdout=b'Pages: 1\nTitle: Example document\n')
+        ref = SimpleNamespace(title='')
+        response = SimpleNamespace(content=content)
+
+        with patch('scripts.reflinks.subprocess.run',
+                   return_value=process) as run:
+            ReferencesRobot.getPDFTitle(ref, response)
+
+        self.assertEqual(ref.title, 'Example document')
+        run.assert_called_once_with(
+            ['pdfinfo', '-'], input=content,
+            capture_output=True, check=False)
+
+
 class TestXMLPageGenerator(TestCase):

     """Test XML Page generator."""

--
To view, visit 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1324317?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I3d95a9e3eeefad76e60e6d4f2231feca599fa4f4
Gerrit-Change-Number: 1324317
Gerrit-PatchSet: 3
Gerrit-Owner: Mahveotm <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to