mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-04-09 02:16:43 +02:00
Move token buffers off the stack (Issue #117)
This commit is contained in:
parent
fe755eac3d
commit
0bd9edc845
@ -110,6 +110,8 @@ pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
bool ret = true; // Return value
|
||||
size_t i; // Looping var
|
||||
_pdfio_strbuf_t *current, // Current string buffer
|
||||
*next; // Next string buffer
|
||||
|
||||
|
||||
// Range check input
|
||||
@ -152,6 +154,12 @@ pdfioFileClose(pdfio_file_t *pdf) // I - PDF file
|
||||
free(pdf->strings[i]);
|
||||
free(pdf->strings);
|
||||
|
||||
for (current = pdf->strbuffers; current; current = next)
|
||||
{
|
||||
next = current->next;
|
||||
free(current);
|
||||
}
|
||||
|
||||
free(pdf);
|
||||
|
||||
return (ret);
|
||||
|
@ -225,6 +225,14 @@ typedef struct _pdfio_objmap_s // PDF object map
|
||||
size_t src_number; // Source object number
|
||||
} _pdfio_objmap_t;
|
||||
|
||||
typedef struct _pdfio_strbuf_s // PDF string buffer
|
||||
{
|
||||
struct _pdfio_strbuf_s *next; // Next string buffer
|
||||
bool bufused; // Is this string buffer being used?
|
||||
char buffer[PDFIO_MAX_STRING + 32];
|
||||
// String buffer
|
||||
} _pdfio_strbuf_t;
|
||||
|
||||
struct _pdfio_file_s // PDF file structure
|
||||
{
|
||||
char *filename; // Filename
|
||||
@ -284,6 +292,7 @@ struct _pdfio_file_s // PDF file structure
|
||||
size_t num_strings, // Number of strings
|
||||
alloc_strings; // Allocated strings
|
||||
char **strings; // Nul-terminated strings
|
||||
_pdfio_strbuf_t *strbuffers; // String buffers
|
||||
};
|
||||
|
||||
struct _pdfio_obj_s // Object
|
||||
@ -391,6 +400,8 @@ extern bool _pdfioObjWriteHeader(pdfio_obj_t *obj) _PDFIO_INTERNAL;
|
||||
extern pdfio_stream_t *_pdfioStreamCreate(pdfio_obj_t *obj, pdfio_obj_t *length_obj, size_t cbsize, pdfio_filter_t compression) _PDFIO_INTERNAL;
|
||||
extern pdfio_stream_t *_pdfioStreamOpen(pdfio_obj_t *obj, bool decode) _PDFIO_INTERNAL;
|
||||
|
||||
extern char *_pdfioStringAllocBuffer(pdfio_file_t *pdf);
|
||||
extern void _pdfioStringFreeBuffer(pdfio_file_t *pdf, char *buffer);
|
||||
extern bool _pdfioStringIsAllocated(pdfio_file_t *pdf, const char *s) _PDFIO_INTERNAL;
|
||||
|
||||
extern void _pdfioTokenClear(_pdfio_token_t *tb) _PDFIO_INTERNAL;
|
||||
|
@ -532,6 +532,41 @@ _pdfio_vsnprintf(pdfio_file_t *pdf, // I - PDF file
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioStringAllocBuffer()' - Allocate a string buffer.
|
||||
//
|
||||
|
||||
char * // O - Buffer or `NULL` on error
|
||||
_pdfioStringAllocBuffer(
|
||||
pdfio_file_t *pdf) // I - PDF file
|
||||
{
|
||||
_pdfio_strbuf_t *current; // Current string buffer
|
||||
|
||||
|
||||
// See if we have an available string buffer...
|
||||
for (current = pdf->strbuffers; current; current = current->next)
|
||||
{
|
||||
if (!current->bufused)
|
||||
{
|
||||
current->bufused = true;
|
||||
return (current->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find one, allocate a new one...
|
||||
if ((current = calloc(1, sizeof(_pdfio_strbuf_t))) == NULL)
|
||||
return (NULL);
|
||||
|
||||
// Add to the linked list of string buffers...
|
||||
current->next = pdf->strbuffers;
|
||||
current->bufused = true;
|
||||
|
||||
pdf->strbuffers = current;
|
||||
|
||||
return (current->buffer);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'pdfioStringCreate()' - Create a durable literal string.
|
||||
//
|
||||
@ -642,6 +677,29 @@ pdfioStringCreatef(
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioStringFreeBuffer()' - Free a string buffer.
|
||||
//
|
||||
|
||||
void
|
||||
_pdfioStringFreeBuffer(
|
||||
pdfio_file_t *pdf, // I - PDF file
|
||||
char *buffer) // I - String buffer
|
||||
{
|
||||
_pdfio_strbuf_t *current; // Current string buffer
|
||||
|
||||
|
||||
for (current = pdf->strbuffers; current; current = current->next)
|
||||
{
|
||||
if (current->buffer == buffer)
|
||||
{
|
||||
current->bufused = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// '_pdfioStringIsAllocated()' - Check whether a string has been allocated.
|
||||
//
|
||||
|
128
pdfio-value.c
128
pdfio-value.c
@ -125,8 +125,7 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
||||
_pdfio_crypto_ctx_t ctx; // Decryption context
|
||||
_pdfio_crypto_cb_t cb; // Decryption callback
|
||||
size_t ivlen; // Number of initialization vector bytes
|
||||
uint8_t temp[PDFIO_MAX_STRING + 32];
|
||||
// Temporary buffer for decryption
|
||||
uint8_t *temp = NULL; // Temporary buffer for decryption
|
||||
size_t templen; // Number of actual data bytes
|
||||
time_t timeval; // Date/time value
|
||||
|
||||
@ -153,11 +152,16 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
||||
|
||||
case PDFIO_VALTYPE_BINARY :
|
||||
// Decrypt the binary string...
|
||||
if (v->value.binary.datalen > (sizeof(temp) - 32))
|
||||
if (v->value.binary.datalen > PDFIO_MAX_STRING)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to read encrypted binary string - too long.");
|
||||
return (false);
|
||||
}
|
||||
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to read encrypted binary string - out of memory.");
|
||||
return (false);
|
||||
}
|
||||
|
||||
ivlen = v->value.binary.datalen;
|
||||
if ((cb = _pdfioCryptoMakeReader(pdf, obj, &ctx, v->value.binary.data, &ivlen)) == NULL)
|
||||
@ -172,6 +176,8 @@ _pdfioValueDecrypt(pdfio_file_t *pdf, // I - PDF file
|
||||
v->value.binary.datalen = templen - temp[templen - 1];
|
||||
else
|
||||
v->value.binary.datalen = templen;
|
||||
|
||||
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||
break;
|
||||
|
||||
case PDFIO_VALTYPE_STRING :
|
||||
@ -301,7 +307,9 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
_pdfio_value_t *v, // I - Value
|
||||
size_t depth) // I - Depth of value
|
||||
{
|
||||
char token[PDFIO_MAX_STRING];// Token buffer
|
||||
_pdfio_value_t *ret = NULL; // Return value
|
||||
char *token = _pdfioStringAllocBuffer(pdf);
|
||||
// Token buffer
|
||||
time_t timeval; // Date/time value
|
||||
#ifdef DEBUG
|
||||
static const char * const valtypes[] =
|
||||
@ -323,8 +331,11 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
|
||||
PDFIO_DEBUG("_pdfioValueRead(pdf=%p, obj=%p, v=%p)\n", pdf, obj, v);
|
||||
|
||||
if (!_pdfioTokenGet(tb, token, sizeof(token)))
|
||||
return (NULL);
|
||||
if (!token)
|
||||
goto done;
|
||||
|
||||
if (!_pdfioTokenGet(tb, token, PDFIO_MAX_STRING))
|
||||
goto done;
|
||||
|
||||
if (!strcmp(token, "["))
|
||||
{
|
||||
@ -332,12 +343,14 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
if (depth >= PDFIO_MAX_DEPTH)
|
||||
{
|
||||
_pdfioFileError(pdf, "Too many nested arrays.");
|
||||
return (NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
v->type = PDFIO_VALTYPE_ARRAY;
|
||||
if ((v->value.array = _pdfioArrayRead(pdf, obj, tb, depth + 1)) == NULL)
|
||||
return (NULL);
|
||||
goto done;
|
||||
|
||||
ret = v;
|
||||
}
|
||||
else if (!strcmp(token, "<<"))
|
||||
{
|
||||
@ -345,29 +358,34 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
if (depth >= PDFIO_MAX_DEPTH)
|
||||
{
|
||||
_pdfioFileError(pdf, "Too many nested dictionaries.");
|
||||
return (NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
v->type = PDFIO_VALTYPE_DICT;
|
||||
if ((v->value.dict = _pdfioDictRead(pdf, obj, tb, depth + 1)) == NULL)
|
||||
return (NULL);
|
||||
goto done;
|
||||
|
||||
ret = v;
|
||||
}
|
||||
else if ((timeval = get_date_time(token + 1)) != 0)
|
||||
{
|
||||
v->type = PDFIO_VALTYPE_DATE;
|
||||
v->value.date = timeval;
|
||||
ret = v;
|
||||
}
|
||||
else if (token[0] == '(')
|
||||
{
|
||||
// String
|
||||
v->type = PDFIO_VALTYPE_STRING;
|
||||
v->value.string = pdfioStringCreate(pdf, token + 1);
|
||||
ret = v;
|
||||
}
|
||||
else if (token[0] == '/')
|
||||
{
|
||||
// Name
|
||||
v->type = PDFIO_VALTYPE_NAME;
|
||||
v->value.name = pdfioStringCreate(pdf, token + 1);
|
||||
ret = v;
|
||||
}
|
||||
else if (token[0] == '<')
|
||||
{
|
||||
@ -380,7 +398,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
if ((v->value.binary.data = (unsigned char *)malloc(v->value.binary.datalen)) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Out of memory for hex string.");
|
||||
return (NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Convert hex to binary...
|
||||
@ -407,6 +425,8 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
|
||||
*dataptr++ = (unsigned char)d;
|
||||
}
|
||||
|
||||
ret = v;
|
||||
}
|
||||
else if (strchr("0123456789-+.", token[0]) != NULL)
|
||||
{
|
||||
@ -494,7 +514,8 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
|
||||
PDFIO_DEBUG("_pdfioValueRead: Returning indirect value %lu %u R.\n", (unsigned long)v->value.indirect.number, v->value.indirect.generation);
|
||||
|
||||
return (v);
|
||||
ret = v;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -502,27 +523,41 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
// If we get here, we have a number...
|
||||
v->type = PDFIO_VALTYPE_NUMBER;
|
||||
v->value.number = _pdfio_strtod(pdf, token);
|
||||
ret = v;
|
||||
}
|
||||
else if (!strcmp(token, "true") || !strcmp(token, "false"))
|
||||
{
|
||||
// Boolean value
|
||||
v->type = PDFIO_VALTYPE_BOOLEAN;
|
||||
v->value.boolean = !strcmp(token, "true");
|
||||
ret = v;
|
||||
}
|
||||
else if (!strcmp(token, "null"))
|
||||
{
|
||||
// null value
|
||||
v->type = PDFIO_VALTYPE_NULL;
|
||||
ret = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pdfioFileError(pdf, "Unexpected '%s' token seen.", token);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
PDFIO_DEBUG("_pdfioValueRead: Returning %s value.\n", valtypes[v->type]);
|
||||
done:
|
||||
|
||||
return (v);
|
||||
if (token)
|
||||
_pdfioStringFreeBuffer(pdf, token);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
PDFIO_DEBUG("_pdfioValueRead: Returning %s value.\n", valtypes[ret->type]);
|
||||
return (ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
PDFIO_DEBUG("_pdfioValueRead: Returning NULL.\n");
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -547,9 +582,10 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
case PDFIO_VALTYPE_BINARY :
|
||||
{
|
||||
size_t databytes; // Bytes to write
|
||||
uint8_t temp[PDFIO_MAX_STRING + 32],
|
||||
// Temporary buffer for encryption
|
||||
uint8_t *temp = NULL, // Temporary buffer for encryption
|
||||
*dataptr; // Pointer into data
|
||||
bool ret = false; // Return value
|
||||
|
||||
|
||||
if (obj && pdf->encryption)
|
||||
{
|
||||
@ -558,11 +594,16 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||
size_t ivlen; // Number of initialization vector bytes
|
||||
|
||||
if (v->value.binary.datalen > (sizeof(temp) - 32))
|
||||
if (v->value.binary.datalen > PDFIO_MAX_STRING)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted binary string - too long.");
|
||||
return (false);
|
||||
}
|
||||
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted binary string - out of memory.");
|
||||
return (false);
|
||||
}
|
||||
|
||||
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
||||
databytes = (cb)(&ctx, temp + ivlen, v->value.binary.data, v->value.binary.datalen) + ivlen;
|
||||
@ -575,18 +616,25 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
}
|
||||
|
||||
if (!_pdfioFilePuts(pdf, "<"))
|
||||
return (false);
|
||||
goto bindone;
|
||||
|
||||
for (; databytes > 1; databytes -= 2, dataptr += 2)
|
||||
{
|
||||
if (!_pdfioFilePrintf(pdf, "%02X%02X", dataptr[0], dataptr[1]))
|
||||
return (false);
|
||||
goto bindone;
|
||||
}
|
||||
|
||||
if (databytes > 0)
|
||||
return (_pdfioFilePrintf(pdf, "%02X>", dataptr[0]));
|
||||
else
|
||||
return (_pdfioFilePuts(pdf, ">"));
|
||||
if (databytes > 0 && !_pdfioFilePrintf(pdf, "%02X", dataptr[0]))
|
||||
goto bindone;
|
||||
|
||||
ret = _pdfioFilePuts(pdf, ">");
|
||||
|
||||
bindone:
|
||||
|
||||
if (temp)
|
||||
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
case PDFIO_VALTYPE_BOOLEAN :
|
||||
@ -611,8 +659,7 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
if (obj && pdf->encryption)
|
||||
{
|
||||
// Write encrypted string...
|
||||
uint8_t temp[PDFIO_MAX_STRING + 32],
|
||||
// Encrypted bytes
|
||||
uint8_t temp[64], // Encrypted bytes
|
||||
*tempptr; // Pointer into encrypted bytes
|
||||
_pdfio_crypto_ctx_t ctx; // Encryption context
|
||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||
@ -663,8 +710,7 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
if (obj && pdf->encryption)
|
||||
{
|
||||
// Write encrypted string...
|
||||
uint8_t temp[PDFIO_MAX_STRING + 32],
|
||||
// Encrypted bytes
|
||||
uint8_t *temp = NULL, // Encrypted bytes
|
||||
*tempptr; // Pointer into encrypted bytes
|
||||
_pdfio_crypto_ctx_t ctx; // Encryption context
|
||||
_pdfio_crypto_cb_t cb; // Encryption callback
|
||||
@ -672,29 +718,41 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
// Length of value
|
||||
ivlen, // Number of initialization vector bytes
|
||||
tempbytes; // Number of output bytes
|
||||
bool ret = false; // Return value
|
||||
|
||||
if (len > (sizeof(temp) - 32))
|
||||
if (len > PDFIO_MAX_STRING)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted string - too long.");
|
||||
return (false);
|
||||
}
|
||||
else if ((temp = (uint8_t *)_pdfioStringAllocBuffer(pdf)) == NULL)
|
||||
{
|
||||
_pdfioFileError(pdf, "Unable to write encrypted string - out of memory.");
|
||||
return (false);
|
||||
}
|
||||
|
||||
cb = _pdfioCryptoMakeWriter(pdf, obj, &ctx, temp, &ivlen);
|
||||
tempbytes = (cb)(&ctx, temp + ivlen, (const uint8_t *)v->value.string, len) + ivlen;
|
||||
|
||||
if (!_pdfioFilePuts(pdf, "<"))
|
||||
return (false);
|
||||
goto strdone;
|
||||
|
||||
for (tempptr = temp; tempbytes > 1; tempbytes -= 2, tempptr += 2)
|
||||
{
|
||||
if (!_pdfioFilePrintf(pdf, "%02X%02X", tempptr[0], tempptr[1]))
|
||||
return (false);
|
||||
goto strdone;
|
||||
}
|
||||
|
||||
if (tempbytes > 0)
|
||||
return (_pdfioFilePrintf(pdf, "%02X>", *tempptr));
|
||||
else
|
||||
return (_pdfioFilePuts(pdf, ">"));
|
||||
if (tempbytes > 0 && !_pdfioFilePrintf(pdf, "%02X", *tempptr))
|
||||
goto strdone;
|
||||
|
||||
ret = _pdfioFilePuts(pdf, ">");
|
||||
|
||||
strdone :
|
||||
|
||||
_pdfioStringFreeBuffer(pdf, (char *)temp);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user