summaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2012-06-24 21:26:28 +0200
committerJay Berkenbilt <ejb@ql.org>2012-06-24 21:56:50 +0200
commit8318d81ada86d4ec8e343c47103932b6bbe45a42 (patch)
treea1ff22dc1584d84829d32c7b1d8698a332877763 /libqpdf
parent781c313058e26b6ab6fda060a652a395d27cdb7a (diff)
downloadqpdf-8318d81ada86d4ec8e343c47103932b6bbe45a42.tar.zst
Fix and test support for files >= 4 GB
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/BitStream.cc2
-rw-r--r--libqpdf/BitWriter.cc2
-rw-r--r--libqpdf/QPDF.cc20
-rw-r--r--libqpdf/QPDFWriter.cc35
-rw-r--r--libqpdf/QPDF_linearization.cc24
-rw-r--r--libqpdf/bits.icc4
-rw-r--r--libqpdf/qpdf-c.cc6
-rw-r--r--libqpdf/qpdf/BitStream.hh2
-rw-r--r--libqpdf/qpdf/BitWriter.hh2
9 files changed, 52 insertions, 45 deletions
diff --git a/libqpdf/BitStream.cc b/libqpdf/BitStream.cc
index 703ce8f2..eb511f72 100644
--- a/libqpdf/BitStream.cc
+++ b/libqpdf/BitStream.cc
@@ -19,7 +19,7 @@ BitStream::reset()
bits_available = 8 * nbytes;
}
-unsigned long
+unsigned long long
BitStream::getBits(int nbits)
{
return read_bits(this->p, this->bit_offset,
diff --git a/libqpdf/BitWriter.cc b/libqpdf/BitWriter.cc
index 441501cb..4fb375cb 100644
--- a/libqpdf/BitWriter.cc
+++ b/libqpdf/BitWriter.cc
@@ -12,7 +12,7 @@ BitWriter::BitWriter(Pipeline* pl) :
}
void
-BitWriter::writeBits(unsigned long val, unsigned int bits)
+BitWriter::writeBits(unsigned long long val, unsigned int bits)
{
write_bits(this->ch, this->bit_offset, val, bits, this->pl);
}
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 6b275d28..743ba93b 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -571,7 +571,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
in_obj = true;
int obj = atoi(m.getMatch(1).c_str());
int gen = atoi(m.getMatch(2).c_str());
- int offset = this->file->getLastOffset();
+ qpdf_offset_t offset = this->file->getLastOffset();
insertXrefEntry(obj, 1, offset, gen, true);
}
else if ((! this->trailer.isInitialized()) &&
@@ -634,6 +634,11 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
}
}
+ if (! this->trailer.isInitialized())
+ {
+ throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ "unable to find trailer while reading xref");
+ }
int size = this->trailer.getKey("/Size").getIntValue();
int max_obj = 0;
if (! xref_table.empty())
@@ -704,7 +709,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
QUtil::int_to_string(i) + ")");
}
- int f1 = atoi(m2.getMatch(1).c_str());
+ // For xref_table, these will always be small enough to be ints
+ qpdf_offset_t f1 = QUtil::string_to_ll(m2.getMatch(1).c_str());
int f2 = atoi(m2.getMatch(2).c_str());
char type = m2.getMatch(3)[0];
if (type == 'f')
@@ -855,7 +861,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset)
return xref_offset;
}
-int
+qpdf_offset_t
QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
{
QPDFObjectHandle dict = xref_obj.getDict();
@@ -957,7 +963,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
{
// Read this entry
unsigned char const* entry = data + (entry_size * i);
- int fields[3];
+ qpdf_offset_t fields[3];
unsigned char const* p = entry;
for (int j = 0; j < 3; ++j)
{
@@ -1002,7 +1008,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
// This is needed by checkLinearization()
this->first_xref_item_offset = xref_offset;
}
- insertXrefEntry(obj, fields[0], fields[1], fields[2]);
+ insertXrefEntry(obj, (int)fields[0], fields[1], (int)fields[2]);
}
if (! this->trailer.isInitialized())
@@ -1031,7 +1037,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
}
void
-QPDF::insertXrefEntry(int obj, int f0, int f1, int f2, bool overwrite)
+QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
{
// Populate the xref table in such a way that the first reference
// to an object that we see, which is the one in the latest xref
@@ -1558,7 +1564,7 @@ QPDF::recoverStreamLength(PointerHolder<InputSource> input,
QPDFXRefEntry const& entry = (*iter).second;
if (entry.getType() == 1)
{
- int obj_offset = entry.getOffset();
+ qpdf_offset_t obj_offset = entry.getOffset();
if ((obj_offset > stream_offset) &&
((this_obj_offset == 0) ||
(this_obj_offset > obj_offset)))
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 308f4c53..26713225 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -540,7 +540,7 @@ QPDFWriter::setDataKey(int objid)
}
int
-QPDFWriter::bytesNeeded(unsigned long n)
+QPDFWriter::bytesNeeded(unsigned long long n)
{
int bytes = 0;
while (n)
@@ -552,10 +552,10 @@ QPDFWriter::bytesNeeded(unsigned long n)
}
void
-QPDFWriter::writeBinary(unsigned long val, unsigned int bytes)
+QPDFWriter::writeBinary(unsigned long long val, unsigned int bytes)
{
- assert(bytes <= sizeof(unsigned long));
- unsigned char data[sizeof(unsigned long)];
+ assert(bytes <= sizeof(unsigned long long));
+ unsigned char data[sizeof(unsigned long long)];
for (unsigned int i = 0; i < bytes; ++i)
{
data[bytes - i - 1] = (unsigned char)(val & 0xff);
@@ -849,7 +849,8 @@ QPDFWriter::unparseChild(QPDFObjectHandle child, int level, int flags)
}
void
-QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream, int prev)
+QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
+ qpdf_offset_t prev)
{
QPDFObjectHandle trailer = pdf.getTrailer();
if (! xref_stream)
@@ -1812,15 +1813,15 @@ QPDFWriter::writeHintStream(int hint_id)
closeObject(hint_id);
}
-int
+qpdf_offset_t
QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size)
{
return writeXRefTable(which, first, last, size, 0, false, 0, 0, 0);
}
-int
+qpdf_offset_t
QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
- int prev, bool suppress_offsets,
+ qpdf_offset_t prev, bool suppress_offsets,
int hint_id, qpdf_offset_t hint_offset,
qpdf_offset_t hint_length)
{
@@ -1838,7 +1839,7 @@ QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
}
else
{
- int offset = 0;
+ qpdf_offset_t offset = 0;
if (! suppress_offsets)
{
offset = this->xref[i].getOffset();
@@ -1858,24 +1859,24 @@ QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
return space_before_zero;
}
-int
-QPDFWriter::writeXRefStream(int objid, int max_id, int max_offset,
+qpdf_offset_t
+QPDFWriter::writeXRefStream(int objid, int max_id, qpdf_offset_t max_offset,
trailer_e which, int first, int last, int size)
{
return writeXRefStream(objid, max_id, max_offset,
which, first, last, size, 0, 0, 0, 0, false);
}
-int
-QPDFWriter::writeXRefStream(int xref_id, int max_id, int max_offset,
+qpdf_offset_t
+QPDFWriter::writeXRefStream(int xref_id, int max_id, qpdf_offset_t max_offset,
trailer_e which, int first, int last, int size,
- int prev, int hint_id,
+ qpdf_offset_t prev, int hint_id,
qpdf_offset_t hint_offset,
qpdf_offset_t hint_length,
bool skip_compression)
{
qpdf_offset_t xref_offset = this->pipeline->getCount();
- int space_before_zero = xref_offset - 1;
+ qpdf_offset_t space_before_zero = xref_offset - 1;
// field 1 contains offsets and object stream identifiers
int f1_size = std::max(bytesNeeded(max_offset),
@@ -1921,7 +1922,7 @@ QPDFWriter::writeXRefStream(int xref_id, int max_id, int max_offset,
case 1:
{
- int offset = e.getOffset();
+ qpdf_offset_t offset = e.getOffset();
if ((hint_id != 0) &&
(i != hint_id) &&
(offset >= hint_offset))
@@ -2309,7 +2310,7 @@ QPDFWriter::writeLinearized()
// Save hint offset since it will be set to zero by
// calling openObject.
- int hint_offset = this->xref[hint_id].getOffset();
+ qpdf_offset_t hint_offset = this->xref[hint_id].getOffset();
// Write hint stream to a buffer
pushPipeline(new Pl_Buffer("hint buffer"));
diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc
index 48bb4d2b..fdd0d702 100644
--- a/libqpdf/QPDF_linearization.cc
+++ b/libqpdf/QPDF_linearization.cc
@@ -18,10 +18,10 @@
#include <math.h>
#include <string.h>
-template <class T>
+template <class T, class int_type>
static void
load_vector_int(BitStream& bit_stream, int nitems, std::vector<T>& vec,
- int bits_wanted, int T::*field)
+ int bits_wanted, int_type T::*field)
{
// nitems times, read bits_wanted from the given bit stream,
// storing results in the ith vector entry.
@@ -144,7 +144,7 @@ QPDF::isLinearized()
QPDFObjectHandle L = candidate.getKey("/L");
if (L.isInteger())
{
- int Li = L.getIntValue();
+ qpdf_offset_t Li = L.getIntValue();
this->file->seek(0, SEEK_END);
if (Li != this->file->tell())
{
@@ -649,11 +649,11 @@ QPDF::maxEnd(ObjUser const& ou)
return end;
}
-int
+qpdf_offset_t
QPDF::getLinearizationOffset(ObjGen const& og)
{
QPDFXRefEntry entry = this->xref_table[og];
- int result = 0;
+ qpdf_offset_t result = 0;
switch (entry.getType())
{
case 1:
@@ -1787,7 +1787,7 @@ static inline int nbits(int val)
int
QPDF::outputLengthNextN(
int in_object, int n,
- std::map<int, size_t> const& lengths,
+ std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber)
{
// Figure out the length of a series of n consecutive objects in
@@ -1808,7 +1808,7 @@ QPDF::outputLengthNextN(
void
QPDF::calculateHPageOffset(
std::map<int, QPDFXRefEntry> const& xref,
- std::map<int, size_t> const& lengths,
+ std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber)
{
// Page Offset Hint Table
@@ -1900,7 +1900,7 @@ QPDF::calculateHPageOffset(
void
QPDF::calculateHSharedObject(
std::map<int, QPDFXRefEntry> const& xref,
- std::map<int, size_t> const& lengths,
+ std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber)
{
CHSharedObject& cso = this->c_shared_object_data;
@@ -1946,7 +1946,7 @@ QPDF::calculateHSharedObject(
void
QPDF::calculateHOutline(
std::map<int, QPDFXRefEntry> const& xref,
- std::map<int, size_t> const& lengths,
+ std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber)
{
HGeneric& cho = this->c_outline_data;
@@ -1967,10 +1967,10 @@ QPDF::calculateHOutline(
cho.first_object, ho.nobjects, lengths, obj_renumber);
}
-template <class T>
+template <class T, class int_type>
static void
write_vector_int(BitWriter& w, int nitems, std::vector<T>& vec,
- int bits, int T::*field)
+ int bits, int_type T::*field)
{
// nitems times, write bits bits from the given field of the ith
// vector to the given bit writer.
@@ -2095,7 +2095,7 @@ QPDF::writeHGeneric(BitWriter& w, HGeneric& t)
void
QPDF::generateHintStream(std::map<int, QPDFXRefEntry> const& xref,
- std::map<int, size_t> const& lengths,
+ std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber,
PointerHolder<Buffer>& hint_buffer,
int& S, int& O)
diff --git a/libqpdf/bits.icc b/libqpdf/bits.icc
index 31765986..bcd7dd85 100644
--- a/libqpdf/bits.icc
+++ b/libqpdf/bits.icc
@@ -15,7 +15,7 @@
// this code includes with the symbol defined.
#ifdef BITS_READ
-static unsigned long
+static unsigned long long
read_bits(unsigned char const*& p, unsigned int& bit_offset,
unsigned int& bits_available, unsigned int bits_wanted)
{
@@ -95,7 +95,7 @@ read_bits(unsigned char const*& p, unsigned int& bit_offset,
#ifdef BITS_WRITE
static void
write_bits(unsigned char& ch, unsigned int& bit_offset,
- unsigned long val, unsigned int bits, Pipeline* pipeline)
+ unsigned long long val, unsigned int bits, Pipeline* pipeline)
{
if (bits > 32)
{
diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc
index 65a5de72..0312ae50 100644
--- a/libqpdf/qpdf-c.cc
+++ b/libqpdf/qpdf-c.cc
@@ -31,7 +31,7 @@ struct _qpdf_data
// Parameters for functions we call
char const* filename; // or description
char const* buffer;
- unsigned long size;
+ unsigned long long size;
char const* password;
bool write_memory;
Buffer* output_buffer;
@@ -218,7 +218,7 @@ char const* qpdf_get_error_filename(qpdf_data qpdf, qpdf_error e)
return e->exc->getFilename().c_str();
}
-unsigned long qpdf_get_error_file_position(qpdf_data qpdf, qpdf_error e)
+unsigned long long qpdf_get_error_file_position(qpdf_data qpdf, qpdf_error e)
{
if (e == 0)
{
@@ -268,7 +268,7 @@ QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename,
QPDF_ERROR_CODE qpdf_read_memory(qpdf_data qpdf,
char const* description,
char const* buffer,
- unsigned long size,
+ unsigned long long size,
char const* password)
{
QPDF_ERROR_CODE status = QPDF_SUCCESS;
diff --git a/libqpdf/qpdf/BitStream.hh b/libqpdf/qpdf/BitStream.hh
index 92bbd735..e45a90ee 100644
--- a/libqpdf/qpdf/BitStream.hh
+++ b/libqpdf/qpdf/BitStream.hh
@@ -13,7 +13,7 @@ class BitStream
QPDF_DLL
void reset();
QPDF_DLL
- unsigned long getBits(int nbits);
+ unsigned long long getBits(int nbits);
QPDF_DLL
void skipToNextByte();
diff --git a/libqpdf/qpdf/BitWriter.hh b/libqpdf/qpdf/BitWriter.hh
index 5eae398f..7e3b07a9 100644
--- a/libqpdf/qpdf/BitWriter.hh
+++ b/libqpdf/qpdf/BitWriter.hh
@@ -15,7 +15,7 @@ class BitWriter
QPDF_DLL
BitWriter(Pipeline* pl);
QPDF_DLL
- void writeBits(unsigned long val, unsigned int bits);
+ void writeBits(unsigned long long val, unsigned int bits);
// Force any partial byte to be written to the pipeline.
QPDF_DLL
void flush();