Description: Fill Libpoppler's new unwillingness to find the last XRef.
 Libpoppler used to report where the last XRef table was. Evidently,
 Libpoppler's developer has since decided that this to be only an internal
 capability of the library, not exposed in the public, nor even in the
 private-public, interface. This patch fills the gap, implementing the
 missing functionality.
 .
 derivations (0.53.20120414-1.2) unstable; urgency=medium
 .
   * Non-maintainer upload.
   * Automatically support poppler api changes (closes: #690161).
     - Thanks to Pino Toscano.
Author: Michael Gilbert <mgilbert@debian.org>
Bug-Debian: https://bugs.debian.org/690161

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- derivations-0.53.20120414.orig/btool/Makefile-subdir
+++ derivations-0.53.20120414/btool/Makefile-subdir
@@ -2,6 +2,7 @@
 # This makefile is meant to be used only when accessed
 # through a symbolic link from an immediate subdirectory.
 
+CXXFLAGS += -std=c++11
 CXXFLAGS += $(shell pkg-config --cflags poppler)
 
 warn := -Wall -Wextra
--- derivations-0.53.20120414.orig/btool/PDF/PDF.cc
+++ derivations-0.53.20120414/btool/PDF/PDF.cc
@@ -1,14 +1,115 @@
 
 #include "PDF.h"
 #include <sys/stat.h>
+#include <fstream>
+#include <string>
+#include <cctype>
 #include "PDF_rep.h"
 
 int PDF::file_length( const PDF &pdf ) {
   return pdf.rep->file_length1;
 }
 
-int PDF::offset_last_xref_table( const PDF &pdf ) {
-  return pdf.rep->xref->getEntry(0)->offset;
+int PDF::offset_last_xref_table( const std::string &pdf_filename ) {
+
+  // Update in 2015, seven years after most of the rest of the file and
+  // program were written:
+  //
+  // In an earlier version of the progam, this function's body was
+  // a one-liner:
+  //
+  //   return pdf.rep->xref->getLastXRefPos();
+  //
+  // That worked fine until Libpoppler changed its interface, since
+  // which it has hidden the required function in the private section
+  // of an interface, unusable here.  In a later version of the
+  // program, this function's body was a different one-liner:
+  //
+  //   return pdf.rep->xref->getEntry(0)->offset;
+  //
+  // This unfortunately does the wrong thing, though, with effects
+  // Salvatore Bonaccorso has noticed and brought to attention.
+  // Accordingly, this function itself must now find the position of
+  // the last XRef table, as follows.
+  //
+  // Fortunately, the PDF standard requires the position of an XRef
+  // table to be given in plain ascii, so finding the position is not
+  // too hard. One must only be sure to find the position of
+  // the *last* XRef table.
+  //
+  // The code is not quite as elegant as it might be, but the whole
+  // program needs cleaning up, so let us not worry about that for now.
+  // (The programmer's C++ style was pretty immature back in 2008 in
+  // any case.)
+  //
+  //
+
+  const char key_token[] = "startxref";
+
+  int offset = -1;
+
+  std::ifstream pdf_file(pdf_filename);
+  bool has_preceding_whitespace = true;
+  char digit_stage[] = " ";
+  int c = std::ifstream::traits_type::eof();
+  const char *p = key_token;
+
+  while (true) {
+
+    c = pdf_file.get();
+    if (c == std::ifstream::traits_type::eof()) goto done;
+
+    if (!has_preceding_whitespace || c != *p) {
+      p = key_token;
+      has_preceding_whitespace = std::isspace(c);
+    }
+
+    else {
+
+      ++p;
+
+      if (!*p) {
+
+        // Skip whitespace between key token and offset.
+        bool has_trailing_whitespace = false;
+        while (true) {
+          c = pdf_file.get();
+          if (c == std::ifstream::traits_type::eof()) goto done;
+          if (!std::isspace(c)) break;
+          has_trailing_whitespace = true;
+        }
+        
+        if (has_trailing_whitespace) {
+
+          // The key token has been found, so prepare to read the offset.
+          offset = -1;
+  
+          // Read the offset.
+          if (std::isdigit(c)) {
+            digit_stage[0] = c;
+            offset = std::atoi(digit_stage);
+            while (true) {
+              c = pdf_file.get();
+              if (c == std::ifstream::traits_type::eof()) goto done;
+              if (!std::isdigit(c)) break;
+              offset *= 10;
+              digit_stage[0] = c;
+              offset += std::atoi(digit_stage);
+            }
+          }
+
+        }
+
+        p = key_token;
+
+      }
+
+    }
+
+  }
+
+  done: return offset;
+
 }
 
 PDF::Iref PDF::iref_catalog( const PDF &pdf ) {
--- derivations-0.53.20120414.orig/btool/PDF/PDF.h
+++ derivations-0.53.20120414/btool/PDF/PDF.h
@@ -44,7 +44,7 @@ namespace PDF {
   struct PDF_rep;
   class  PDF;
   int  file_length           ( const PDF &pdf );
-  int  offset_last_xref_table( const PDF &pdf );
+  int  offset_last_xref_table( const std::string &pdf_filename );
   Iref iref_catalog          ( const PDF &pdf );
   Iref iref_info             ( const PDF &pdf );
   int  n_obj                 ( const PDF &pdf );
@@ -75,7 +75,7 @@ class PDF::PDF {
     explicit PDF( const std::string &filename );
     ~PDF();
     friend int  file_length           ( const PDF &pdf );
-    friend int  offset_last_xref_table( const PDF &pdf );
+    friend int  offset_last_xref_table( const std::string &pdf_filename );
     friend Iref iref_catalog          ( const PDF &pdf );
     friend Iref iref_info             ( const PDF &pdf );
     friend int  n_obj                 ( const PDF &pdf );
--- derivations-0.53.20120414.orig/btool/PDF/update_catalog.cc
+++ derivations-0.53.20120414/btool/PDF/update_catalog.cc
@@ -212,7 +212,8 @@ string PDF::add_title_to_info(
 string PDF::update_trailer(
   PDF &pdf,
   const int n_pdf_obj,
-  const int offset_xref
+  const int offset_xref,
+  const std::string &pdf_filename
 ) {
 
   PDF_rep *const rep = pdf.get_PDF_rep(magic);
@@ -241,7 +242,7 @@ string PDF::update_trailer(
   char s_Prev[] = "Prev";
   {
     Object obj;
-    obj.initInt( offset_last_xref_table(pdf) );
+    obj.initInt( offset_last_xref_table(pdf_filename) );
     new_trailer->add( s_Prev, &obj );
   }
 
--- derivations-0.53.20120414.orig/btool/PDF/update_catalog.h
+++ derivations-0.53.20120414/btool/PDF/update_catalog.h
@@ -21,7 +21,8 @@ namespace PDF {
   std::string update_trailer(
     PDF &pdf,
     int n_pdf_obj,
-    int offset_xref
+    int offset_xref,
+    const std::string &pdf_filename
   );
 }
 
--- derivations-0.53.20120414.orig/btool/PDF/updator.cc
+++ derivations-0.53.20120414/btool/PDF/updator.cc
@@ -15,6 +15,7 @@ string PDF::updator(
   PDF &pdf,
   const Page_no::PS_page_numbering &nog,
   const TOC::Table &toc,
+  const std::string &pdf_filename,
   const string &title
 ) {
 
@@ -79,7 +80,8 @@ string PDF::updator(
   string trailer = update_trailer(
     pdf,
     n_obj(pdf) + outline.size(),
-    file_offset
+    file_offset,
+    pdf_filename
   );
 
   string res;
@@ -110,6 +112,7 @@ string PDF::updator(
     pdf,
     Page_no::PS_page_numbering( filename_ps ),
     TOC::Table( filename_toc ),
+    filename_pdf,
     title
   );
 }
--- derivations-0.53.20120414.orig/btool/PDF/updator.h
+++ derivations-0.53.20120414/btool/PDF/updator.h
@@ -19,6 +19,7 @@ namespace PDF {
     PDF &pdf,
     const Page_no::PS_page_numbering &nog,
     const TOC::Table &toc,
+    const std::string &pdf_filename,
     const std::string &title = std::string()
   );
   std::string updator(
