Repository: qpdf/qpdf
Pull request #295 (2019-02-14 19:05:33)

Undefined functions because of missing std:: or header.
My Embarcadero C++Builder RAD 10.2 was missing either headers or the explicit namespace `std::` on some function calls. Again, I think being explicit here shouldn't interfere with other compilers.


Patch:
diff --git a/ChangeLog b/ChangeLog
index 62c20948..9f33d4cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2019-03-11  Jay Berkenbilt  <ejb@ql.org>
+
+	* JSON serialization: add missing leading 0 to decimal values
+	between -1 and 1. Fixes #308.
+
 2019-02-01  Jay Berkenbilt  <ejb@ql.org>
 
 	* 8.4.0: release
diff --git a/README-maintainer b/README-maintainer
index ec257178..4b47a809 100644
--- a/README-maintainer
+++ b/README-maintainer
@@ -129,7 +129,7 @@ gpg --detach-sign --armor qpdf-$version.tar.gz
 \rm -f *.{md5,sha1,sha512}
 files=(*)
 for i in md5 sha1 sha512; do
-  ${i}sum $files >| qpdf-$version.$i
+  ${i}sum ${files[*]} >| qpdf-$version.$i
   gpg --clearsign --armor qpdf-$version.$i
   mv qpdf-$version.$i.asc qpdf-$version.$i
 done
diff --git a/TODO b/TODO
index 0bd28ad7..fe6f1569 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,9 @@
+Before Next Release
+===================
+
+ * Make sure it is clear to downloaders where they can find my public
+   key for verifying downloads.
+
 Soon
 ====
 
diff --git a/examples/pdf-split-pages.cc b/examples/pdf-split-pages.cc
index aa089e5a..b6dd701b 100644
--- a/examples/pdf-split-pages.cc
+++ b/examples/pdf-split-pages.cc
@@ -8,9 +8,10 @@
 #include <qpdf/QPDFPageDocumentHelper.hh>
 #include <qpdf/QPDFWriter.hh>
 #include <qpdf/QUtil.hh>
-#include <string>
+
 #include <iostream>
-#include <cstdlib>
+#include <stdlib.h>
+#include <string>
 
 static char const* whoami = 0;
 static bool static_id = false;
diff --git a/include/qpdf/DLL.h b/include/qpdf/DLL.h
index ccd05fce..1e5d8a1a 100644
--- a/include/qpdf/DLL.h
+++ b/include/qpdf/DLL.h
@@ -25,8 +25,13 @@
 
 #if defined(_WIN32) && defined(DLL_EXPORT)
 # define QPDF_DLL __declspec(dllexport)
+# define QPDF_DLL_EXCEPTION
+#elif __GNUC__ >= 4
+# define QPDF_DLL __attribute__ ((visibility ("default")))
+# define QPDF_DLL_EXCEPTION __attribute__ ((visibility ("default")))
 #else
 # define QPDF_DLL
+# define QPDF_DLL_EXCEPTION
 #endif
 
 #endif /* QPDF_DLL_HH */
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index 634c9bd1..6de51ef3 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -30,8 +30,10 @@
 #include <map>
 #include <list>
 #include <iostream>
+#include <vector>
 
 #include <qpdf/QPDFExc.hh>
+#include <qpdf/QPDFObjectHandle.hh>
 #include <qpdf/QPDFObjGen.hh>
 #include <qpdf/QPDFXRefEntry.hh>
 #include <qpdf/QPDFObjectHandle.hh>
@@ -1298,6 +1300,7 @@ class QPDF
     class Members
     {
         friend class QPDF;
+        friend class ResolveRecorder;
 
       public:
         QPDF_DLL
diff --git a/include/qpdf/QPDFExc.hh b/include/qpdf/QPDFExc.hh
index fe0aa1d5..c538eb4d 100644
--- a/include/qpdf/QPDFExc.hh
+++ b/include/qpdf/QPDFExc.hh
@@ -29,7 +29,7 @@
 #include <string>
 #include <stdexcept>
 
-class QPDFExc: public std::runtime_error
+class QPDF_DLL_EXCEPTION QPDFExc: public std::runtime_error
 {
   public:
     QPDF_DLL
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index b181bd79..978cddff 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -1028,6 +1028,7 @@ class QPDFObjectHandle
 
     class Members
     {
+        friend class ObjAccessor;
         friend class QPDFObjectHandle;
 
       public:
diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh
index c4e48713..cef8ea08 100644
--- a/include/qpdf/QPDFSystemError.hh
+++ b/include/qpdf/QPDFSystemError.hh
@@ -29,7 +29,7 @@
 #include <string>
 #include <stdexcept>
 
-class QPDFSystemError: public std::runtime_error
+class QPDF_DLL_EXCEPTION QPDFSystemError: public std::runtime_error
 {
   public:
     QPDF_DLL
diff --git a/ispell-words b/ispell-words
index 9d60b74d..ff0f3120 100644
--- a/ispell-words
+++ b/ispell-words
@@ -400,7 +400,6 @@ cso
 csoe
 css
 cstdio
-cstdlib
 cstr
 cstring
 ctest
diff --git a/libqpdf/Pl_DCT.cc b/libqpdf/Pl_DCT.cc
index 8e1a5177..ceecc518 100644
--- a/libqpdf/Pl_DCT.cc
+++ b/libqpdf/Pl_DCT.cc
@@ -2,10 +2,11 @@
 
 #include <qpdf/QUtil.hh>
 #include <qpdf/QTC.hh>
+
 #include <setjmp.h>
-#include <string>
 #include <stdexcept>
-#include <cstdlib>
+#include <stdlib.h>
+#include <string>
 
 #if BITS_IN_JSAMPLE != 8
 # error "qpdf does not support libjpeg built with BITS_IN_JSAMPLE != 8"
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index e9d0b77a..61fd7920 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -4,6 +4,7 @@
 #include <vector>
 #include <map>
 #include <algorithm>
+#include <stdlib.h>
 #include <string.h>
 #include <memory.h>
 
diff --git a/libqpdf/QPDFTokenizer.cc b/libqpdf/QPDFTokenizer.cc
index 80fcf347..ff5ebe15 100644
--- a/libqpdf/QPDFTokenizer.cc
+++ b/libqpdf/QPDFTokenizer.cc
@@ -10,8 +10,8 @@
 #include <qpdf/QPDFObjectHandle.hh>
 
 #include <stdexcept>
+#include <stdlib.h>
 #include <string.h>
-#include <cstdlib>
 
 static bool is_delimiter(char ch)
 {
diff --git a/libqpdf/QPDF_Real.cc b/libqpdf/QPDF_Real.cc
index b28c2f70..b4c8283f 100644
--- a/libqpdf/QPDF_Real.cc
+++ b/libqpdf/QPDF_Real.cc
@@ -25,7 +25,30 @@ QPDF_Real::unparse()
 JSON
 QPDF_Real::getJSON()
 {
-    return JSON::makeNumber(this->val);
+    // While PDF allows .x or -.x, JSON does not. Rather than
+    // convering from string to double and back, just handle this as a
+    // special case for JSON.
+    std::string result;
+    if (this->val.length() == 0)
+    {
+        // Can't really happen...
+        result = "0";
+    }
+    else if (this->val.at(0) == '.')
+    {
+        result = "0" + this->val;
+    }
+    else if ((this->val.length() >= 2) &&
+             (this->val.at(0) == '-') &&
+             (this->val.at(1) == '.'))
+    {
+        result = "-0." + this->val.substr(2);
+    }
+    else
+    {
+        result = this->val;
+    }
+    return JSON::makeNumber(result);
 }
 
 QPDFObject::object_type_e
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index 58646ade..7ea3f5e7 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -529,7 +529,9 @@ QUtil::hex_decode(std::string const& input)
 void
 QUtil::binary_stdout()
 {
-#ifdef _WIN32
+#if defined(_WIN32) && defined(__BORLANDC__)
+     setmode(_fileno(stdout), _O_BINARY);
+#elif defined(_WIN32)
     _setmode(_fileno(stdout), _O_BINARY);
 #endif
 }
@@ -537,7 +539,9 @@ QUtil::binary_stdout()
 void
 QUtil::binary_stdin()
 {
-#ifdef _WIN32
+#if defined(_WIN32) && defined(__BORLANDC__)
+     setmode(_fileno(stdin), _O_BINARY);
+#elif defined(_WIN32)
     _setmode(_fileno(stdin), _O_BINARY);
 #endif
 }
@@ -918,7 +922,9 @@ QUtil::read_lines_from_file(std::istream& in)
 int
 QUtil::strcasecmp(char const *s1, char const *s2)
 {
-#ifdef _WIN32
+#if defined(_WIN32) && defined(__BORLANDC__)
+    return stricmp(s1, s2);
+#elif defined(_WIN32)
     return _stricmp(s1, s2);
 #else
     return ::strcasecmp(s1, s2);
diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc
index 17484b3f..4ec0a48c 100644
--- a/qpdf/qpdf.cc
+++ b/qpdf/qpdf.cc
@@ -3836,7 +3836,7 @@ ImageOptimizer::makePipeline(std::string const& description, Pipeline* next)
         h_obj.isInteger() ? h_obj.getIntValue() : h_obj.getNumericValue());
     std::string colorspace = (colorspace_obj.isName() ?
                               colorspace_obj.getName() :
-                              "");
+                              std::string());
     int components = 0;
     J_COLOR_SPACE cs = JCS_UNKNOWN;
     if (colorspace == "/DeviceRGB")


Test patch:
diff --git a/libtests/json.cc b/libtests/json.cc
index 1a9123ad..e3086c18 100644
--- a/libtests/json.cc
+++ b/libtests/json.cc
@@ -3,7 +3,7 @@
 #include <iostream>
 #include <assert.h>
 
-static void check(JSON& j, std::string const& exp)
+static void check(JSON const& j, std::string const& exp)
 {
     if (exp != j.unparse())
     {
@@ -69,6 +69,10 @@ static void test_main()
           "  ],\n"
           "  \"yes\": false\n"
           "}");
+    check(QPDFObjectHandle::newReal("0.12").getJSON(), "0.12");
+    check(QPDFObjectHandle::newReal(".34").getJSON(), "0.34");
+    check(QPDFObjectHandle::newReal("-0.56").getJSON(), "-0.56");
+    check(QPDFObjectHandle::newReal("-.78").getJSON(), "-0.78");
 }
 
 static void check_schema(JSON& obj, JSON& schema, bool exp,
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index b6b33977..a968404c 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -1675,6 +1675,7 @@ $n_tests += 4;
     for (my $i = 1; $i <= 201; ++$i)
     {
         open(F, sprintf(">%03d-kfo.pdf", $i)) or die;
+        binmode F;
         print F $content;
         close(F);
     }
@@ -1688,7 +1689,7 @@ $td->runtest("disable keep files open",
 $td->runtest("don't disable keep files open",
              {$td->COMMAND =>
                   "qpdf --verbose --static-id --empty" .
-                  " --pages 1*kfo.pdf -- a.pdf"},
+                  " --pages 11*kfo.pdf -- a.pdf"},
              {$td->FILE => "enable-kfo.out", $td->EXIT_STATUS => 0},
              $td->NORMALIZE_NEWLINES);
 $td->runtest("explict keep files open",
diff --git a/qpdf/qtest/qpdf/enable-kfo.out b/qpdf/qtest/qpdf/enable-kfo.out
index b889638c..82e1b7c4 100644
--- a/qpdf/qtest/qpdf/enable-kfo.out
+++ b/qpdf/qtest/qpdf/enable-kfo.out
@@ -1,14 +1,4 @@
 qpdf: selecting --keep-open-files=y
-qpdf: processing 100-kfo.pdf
-qpdf: processing 101-kfo.pdf
-qpdf: processing 102-kfo.pdf
-qpdf: processing 103-kfo.pdf
-qpdf: processing 104-kfo.pdf
-qpdf: processing 105-kfo.pdf
-qpdf: processing 106-kfo.pdf
-qpdf: processing 107-kfo.pdf
-qpdf: processing 108-kfo.pdf
-qpdf: processing 109-kfo.pdf
 qpdf: processing 110-kfo.pdf
 qpdf: processing 111-kfo.pdf
 qpdf: processing 112-kfo.pdf
@@ -19,97 +9,7 @@ qpdf: processing 116-kfo.pdf
 qpdf: processing 117-kfo.pdf
 qpdf: processing 118-kfo.pdf
 qpdf: processing 119-kfo.pdf
-qpdf: processing 120-kfo.pdf
-qpdf: processing 121-kfo.pdf
-qpdf: processing 122-kfo.pdf
-qpdf: processing 123-kfo.pdf
-qpdf: processing 124-kfo.pdf
-qpdf: processing 125-kfo.pdf
-qpdf: processing 126-kfo.pdf
-qpdf: processing 127-kfo.pdf
-qpdf: processing 128-kfo.pdf
-qpdf: processing 129-kfo.pdf
-qpdf: processing 130-kfo.pdf
-qpdf: processing 131-kfo.pdf
-qpdf: processing 132-kfo.pdf
-qpdf: processing 133-kfo.pdf
-qpdf: processing 134-kfo.pdf
-qpdf: processing 135-kfo.pdf
-qpdf: processing 136-kfo.pdf
-qpdf: processing 137-kfo.pdf
-qpdf: processing 138-kfo.pdf
-qpdf: processing 139-kfo.pdf
-qpdf: processing 140-kfo.pdf
-qpdf: processing 141-kfo.pdf
-qpdf: processing 142-kfo.pdf
-qpdf: processing 143-kfo.pdf
-qpdf: processing 144-kfo.pdf
-qpdf: processing 145-kfo.pdf
-qpdf: processing 146-kfo.pdf
-qpdf: processing 147-kfo.pdf
-qpdf: processing 148-kfo.pdf
-qpdf: processing 149-kfo.pdf
-qpdf: processing 150-kfo.pdf
-qpdf: processing 151-kfo.pdf
-qpdf: processing 152-kfo.pdf
-qpdf: processing 153-kfo.pdf
-qpdf: processing 154-kfo.pdf
-qpdf: processing 155-kfo.pdf
-qpdf: processing 156-kfo.pdf
-qpdf: processing 157-kfo.pdf
-qpdf: processing 158-kfo.pdf
-qpdf: processing 159-kfo.pdf
-qpdf: processing 160-kfo.pdf
-qpdf: processing 161-kfo.pdf
-qpdf: processing 162-kfo.pdf
-qpdf: processing 163-kfo.pdf
-qpdf: processing 164-kfo.pdf
-qpdf: processing 165-kfo.pdf
-qpdf: processing 166-kfo.pdf
-qpdf: processing 167-kfo.pdf
-qpdf: processing 168-kfo.pdf
-qpdf: processing 169-kfo.pdf
-qpdf: processing 170-kfo.pdf
-qpdf: processing 171-kfo.pdf
-qpdf: processing 172-kfo.pdf
-qpdf: processing 173-kfo.pdf
-qpdf: processing 174-kfo.pdf
-qpdf: processing 175-kfo.pdf
-qpdf: processing 176-kfo.pdf
-qpdf: processing 177-kfo.pdf
-qpdf: processing 178-kfo.pdf
-qpdf: processing 179-kfo.pdf
-qpdf: processing 180-kfo.pdf
-qpdf: processing 181-kfo.pdf
-qpdf: processing 182-kfo.pdf
-qpdf: processing 183-kfo.pdf
-qpdf: processing 184-kfo.pdf
-qpdf: processing 185-kfo.pdf
-qpdf: processing 186-kfo.pdf
-qpdf: processing 187-kfo.pdf
-qpdf: processing 188-kfo.pdf
-qpdf: processing 189-kfo.pdf
-qpdf: processing 190-kfo.pdf
-qpdf: processing 191-kfo.pdf
-qpdf: processing 192-kfo.pdf
-qpdf: processing 193-kfo.pdf
-qpdf: processing 194-kfo.pdf
-qpdf: processing 195-kfo.pdf
-qpdf: processing 196-kfo.pdf
-qpdf: processing 197-kfo.pdf
-qpdf: processing 198-kfo.pdf
-qpdf: processing 199-kfo.pdf
 qpdf: removing unreferenced pages from primary input
-qpdf: adding pages from 100-kfo.pdf
-qpdf: adding pages from 101-kfo.pdf
-qpdf: adding pages from 102-kfo.pdf
-qpdf: adding pages from 103-kfo.pdf
-qpdf: adding pages from 104-kfo.pdf
-qpdf: adding pages from 105-kfo.pdf
-qpdf: adding pages from 106-kfo.pdf
-qpdf: adding pages from 107-kfo.pdf
-qpdf: adding pages from 108-kfo.pdf
-qpdf: adding pages from 109-kfo.pdf
 qpdf: adding pages from 110-kfo.pdf
 qpdf: adding pages from 111-kfo.pdf
 qpdf: adding pages from 112-kfo.pdf
@@ -120,84 +20,4 @@ qpdf: adding pages from 116-kfo.pdf
 qpdf: adding pages from 117-kfo.pdf
 qpdf: adding pages from 118-kfo.pdf
 qpdf: adding pages from 119-kfo.pdf
-qpdf: adding pages from 120-kfo.pdf
-qpdf: adding pages from 121-kfo.pdf
-qpdf: adding pages from 122-kfo.pdf
-qpdf: adding pages from 123-kfo.pdf
-qpdf: adding pages from 124-kfo.pdf
-qpdf: adding pages from 125-kfo.pdf
-qpdf: adding pages from 126-kfo.pdf
-qpdf: adding pages from 127-kfo.pdf
-qpdf: adding pages from 128-kfo.pdf
-qpdf: adding pages from 129-kfo.pdf
-qpdf: adding pages from 130-kfo.pdf
-qpdf: adding pages from 131-kfo.pdf
-qpdf: adding pages from 132-kfo.pdf
-qpdf: adding pages from 133-kfo.pdf
-qpdf: adding pages from 134-kfo.pdf
-qpdf: adding pages from 135-kfo.pdf
-qpdf: adding pages from 136-kfo.pdf
-qpdf: adding pages from 137-kfo.pdf
-qpdf: adding pages from 138-kfo.pdf
-qpdf: adding pages from 139-kfo.pdf
-qpdf: adding pages from 140-kfo.pdf
-qpdf: adding pages from 141-kfo.pdf
-qpdf: adding pages from 142-kfo.pdf
-qpdf: adding pages from 143-kfo.pdf
-qpdf: adding pages from 144-kfo.pdf
-qpdf: adding pages from 145-kfo.pdf
-qpdf: adding pages from 146-kfo.pdf
-qpdf: adding pages from 147-kfo.pdf
-qpdf: adding pages from 148-kfo.pdf
-qpdf: adding pages from 149-kfo.pdf
-qpdf: adding pages from 150-kfo.pdf
-qpdf: adding pages from 151-kfo.pdf
-qpdf: adding pages from 152-kfo.pdf
-qpdf: adding pages from 153-kfo.pdf
-qpdf: adding pages from 154-kfo.pdf
-qpdf: adding pages from 155-kfo.pdf
-qpdf: adding pages from 156-kfo.pdf
-qpdf: adding pages from 157-kfo.pdf
-qpdf: adding pages from 158-kfo.pdf
-qpdf: adding pages from 159-kfo.pdf
-qpdf: adding pages from 160-kfo.pdf
-qpdf: adding pages from 161-kfo.pdf
-qpdf: adding pages from 162-kfo.pdf
-qpdf: adding pages from 163-kfo.pdf
-qpdf: adding pages from 164-kfo.pdf
-qpdf: adding pages from 165-kfo.pdf
-qpdf: adding pages from 166-kfo.pdf
-qpdf: adding pages from 167-kfo.pdf
-qpdf: adding pages from 168-kfo.pdf
-qpdf: adding pages from 169-kfo.pdf
-qpdf: adding pages from 170-kfo.pdf
-qpdf: adding pages from 171-kfo.pdf
-qpdf: adding pages from 172-kfo.pdf
-qpdf: adding pages from 173-kfo.pdf
-qpdf: adding pages from 174-kfo.pdf
-qpdf: adding pages from 175-kfo.pdf
-qpdf: adding pages from 176-kfo.pdf
-qpdf: adding pages from 177-kfo.pdf
-qpdf: adding pages from 178-kfo.pdf
-qpdf: adding pages from 179-kfo.pdf
-qpdf: adding pages from 180-kfo.pdf
-qpdf: adding pages from 181-kfo.pdf
-qpdf: adding pages from 182-kfo.pdf
-qpdf: adding pages from 183-kfo.pdf
-qpdf: adding pages from 184-kfo.pdf
-qpdf: adding pages from 185-kfo.pdf
-qpdf: adding pages from 186-kfo.pdf
-qpdf: adding pages from 187-kfo.pdf
-qpdf: adding pages from 188-kfo.pdf
-qpdf: adding pages from 189-kfo.pdf
-qpdf: adding pages from 190-kfo.pdf
-qpdf: adding pages from 191-kfo.pdf
-qpdf: adding pages from 192-kfo.pdf
-qpdf: adding pages from 193-kfo.pdf
-qpdf: adding pages from 194-kfo.pdf
-qpdf: adding pages from 195-kfo.pdf
-qpdf: adding pages from 196-kfo.pdf
-qpdf: adding pages from 197-kfo.pdf
-qpdf: adding pages from 198-kfo.pdf
-qpdf: adding pages from 199-kfo.pdf
 qpdf: wrote file a.pdf
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 462a8a23..d3abbe46 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -1631,7 +1631,7 @@ void runtest(int n, char const* filename1, char const* arg2)
                 QPDFFormFieldObjectHelper parent(node.getParent());
                 std::cout << "  Parent: "
                           << (parent.isNull()
-                              ? "none"
+                              ? std::string("none")
                               : parent.getObjectHandle().unparse())
                           << std::endl;
                 node = parent;