[poppler] 2 commits - config.h.cmake ConfigureChecks.cmake poppler/PageLabelInfo.cc poppler/PageLabelInfo_p.h qt5/tests

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Oct 1 23:47:10 UTC 2018


 ConfigureChecks.cmake             |    2 ++
 config.h.cmake                    |    3 +++
 poppler/PageLabelInfo.cc          |    7 ++++---
 poppler/PageLabelInfo_p.h         |   34 ++++++++++++++++++++++++++++++++++
 qt5/tests/check_pagelabelinfo.cpp |   20 ++++++++++++++++++++
 5 files changed, 63 insertions(+), 3 deletions(-)

New commits:
commit a6f88881d41f064a4c2438d4e1b532872a879b0c
Author: Adam Reichold <adam.reichold at t-online.de>
Date:   Sun Sep 23 09:56:51 2018 +0200

    Put (optional) usage of codecvt behind a configure check s.t. we at least compile even if we do not properly handle the unicode page label.

diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 6a910394..fa0f1403 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -4,6 +4,7 @@
 # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
 
 include(CheckIncludeFile)
+include(CheckIncludeFileCXX)
 include(CheckIncludeFiles)
 include(CheckSymbolExists)
 include(CheckFunctionExists)
@@ -17,6 +18,7 @@ check_include_files(stdlib.h HAVE_STDLIB_H)
 check_include_files(sys/mman.h HAVE_SYS_MMAN_H)
 check_include_files(sys/stat.h HAVE_SYS_STAT_H)
 check_include_files(unistd.h HAVE_UNISTD_H)
+check_include_file_cxx(codecvt HAVE_CODECVT)
 
 check_function_exists(fseek64 HAVE_FSEEK64)
 check_function_exists(fseeko HAVE_FSEEKO)
diff --git a/config.h.cmake b/config.h.cmake
index 74355a69..7989cbfb 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -117,6 +117,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #cmakedefine HAVE_UNISTD_H 1
 
+/* Define to 1 if you have the <codecvt> header file. */
+#cmakedefine HAVE_CODECVT
+
 /* Define to 1 if you have a big endian machine */
 #cmakedefine WORDS_BIGENDIAN 1
 
diff --git a/poppler/PageLabelInfo_p.h b/poppler/PageLabelInfo_p.h
index 36abe0e1..6553c325 100644
--- a/poppler/PageLabelInfo_p.h
+++ b/poppler/PageLabelInfo_p.h
@@ -14,20 +14,19 @@
 
 /* http://mathworld.wolfram.com/RomanNumerals.html */
 
+#include "config.h"
+
+#ifdef HAVE_CODECVT
 #include <locale>
 #include <codecvt>
+#endif
 
 #include "goo/GooString.h"
 #include "Error.h"
 
 static std::pair<int,bool> fromDecimal(const char *const begin, const char *const end, const bool unicode) {
-  if (!unicode) {
-    char *parsed;
-    const int number = std::strtol(begin, &parsed, 10);
-    if (parsed >= end) {
-      return std::make_pair(number, true);
-    }
-  } else {
+#ifdef HAVE_CODECVT
+  if (unicode) {
     std::wstring_convert<std::codecvt_utf16<wchar_t>> converter;
     const auto str = converter.from_bytes(begin, end);
 
@@ -43,8 +42,13 @@ static std::pair<int,bool> fromDecimal(const char *const begin, const char *cons
       return std::make_pair(number, true);
     }
   }
+#else
+  (void)unicode;
+#endif
 
-  return std::make_pair(0, false);
+  char *parsed;
+  const int number = std::strtol(begin, &parsed, 10);
+  return std::make_pair(number, parsed >= end);
 }
 
 static int fromRoman(const char *buffer) {
commit 65c8bc1eefea0b99e46d4190dc61ead216088283
Author: Adam Reichold <adam.reichold at t-online.de>
Date:   Sun Sep 23 00:45:04 2018 +0200

    Parse Unicode decimals as well as ASCII decimals when resolving page labels.

diff --git a/poppler/PageLabelInfo.cc b/poppler/PageLabelInfo.cc
index 96c4c333..3053aa05 100644
--- a/poppler/PageLabelInfo.cc
+++ b/poppler/PageLabelInfo.cc
@@ -102,8 +102,9 @@ GBool PageLabelInfo::labelToIndex(GooString *label, int *index) const
 {
   const char *const str = label->getCString();
   const std::size_t strLen = label->getLength();
-  char *end;
+  const bool strUnicode = label->hasUnicodeMarker();
   int number;
+  bool ok;
 
   for (const auto& interval : intervals) {
     const std::size_t prefixLen = interval.prefix.size();
@@ -112,8 +113,8 @@ GBool PageLabelInfo::labelToIndex(GooString *label, int *index) const
 
     switch (interval.style) {
     case Interval::Arabic:
-      number = strtol(str + prefixLen, &end, 10);
-      if (*end == '\0' && number - interval.first < interval.length) {
+      std::tie(number, ok) = fromDecimal(str + prefixLen, str + strLen, strUnicode);
+      if (ok && number - interval.first < interval.length) {
     *index = interval.base + number - interval.first;
 	return gTrue;
       }
diff --git a/poppler/PageLabelInfo_p.h b/poppler/PageLabelInfo_p.h
index 34823cc6..36abe0e1 100644
--- a/poppler/PageLabelInfo_p.h
+++ b/poppler/PageLabelInfo_p.h
@@ -14,9 +14,39 @@
 
 /* http://mathworld.wolfram.com/RomanNumerals.html */
 
+#include <locale>
+#include <codecvt>
+
 #include "goo/GooString.h"
 #include "Error.h"
 
+static std::pair<int,bool> fromDecimal(const char *const begin, const char *const end, const bool unicode) {
+  if (!unicode) {
+    char *parsed;
+    const int number = std::strtol(begin, &parsed, 10);
+    if (parsed >= end) {
+      return std::make_pair(number, true);
+    }
+  } else {
+    std::wstring_convert<std::codecvt_utf16<wchar_t>> converter;
+    const auto str = converter.from_bytes(begin, end);
+
+    // Skip BOM since wcstol seems unable to handle it.
+    const wchar_t *c_str = str.c_str();
+    if (*c_str == wchar_t{0xfeff}) {
+      ++c_str;
+    }
+
+    wchar_t *parsed;
+    const int number = std::wcstol(c_str, &parsed, 10);
+    if (parsed >= str.data() + str.size()) {
+      return std::make_pair(number, true);
+    }
+  }
+
+  return std::make_pair(0, false);
+}
+
 static int fromRoman(const char *buffer) {
   int digit_value, prev_digit_value, value;
   int i;
diff --git a/qt5/tests/check_pagelabelinfo.cpp b/qt5/tests/check_pagelabelinfo.cpp
index a428e059..1b13be95 100644
--- a/qt5/tests/check_pagelabelinfo.cpp
+++ b/qt5/tests/check_pagelabelinfo.cpp
@@ -1,17 +1,37 @@
 #include <QtTest/QtTest>
 
+#include <poppler-private.h>
+
 #include "PageLabelInfo_p.h"
 
 class TestPageLabelInfo : public QObject
 {
     Q_OBJECT
 private slots:
+    void testFromDecimal();
+    void testFromDecimalUnicode();
     void testToRoman();
     void testFromRoman();
     void testToLatin();
     void testFromLatin();
 };
 
+void TestPageLabelInfo::testFromDecimal()
+{
+  std::string str{"2342"};
+  const auto res = fromDecimal(str.data(), str.data() + str.size(), false);
+  QCOMPARE(res.first, 2342);
+  QCOMPARE(res.second, true);
+}
+
+void TestPageLabelInfo::testFromDecimalUnicode()
+{
+  std::unique_ptr<GooString> str(Poppler::QStringToUnicodeGooString(QString::fromLocal8Bit("2342")));
+  const auto res = fromDecimal(str->getCString(), str->getCString() + str->getLength(), str->hasUnicodeMarker());
+  QCOMPARE(res.first, 2342);
+  QCOMPARE(res.second, true);
+}
+
 void TestPageLabelInfo::testToRoman()
 {
     GooString str;


More information about the poppler mailing list