Fix pdfioStringCreate - was returning a char ** instead of a char *, causing

crashes/corruption.

Optimize dict allocation/sorting.

Add more values that are displayed by the testpdfio unit test program.
This commit is contained in:
Michael R Sweet 2021-05-05 13:51:42 -04:00
parent 4abb91ca24
commit c0b18a7e4f
No known key found for this signature in database
GPG Key ID: 999559A027815955
3 changed files with 35 additions and 13 deletions

View File

@ -739,6 +739,7 @@ _pdfioDictSetValue(
if ((pair = (_pdfio_pair_t *)bsearch(&pkey, dict->pairs, dict->num_pairs, sizeof(_pdfio_pair_t), (int (*)(const void *, const void *))compare_pairs)) != NULL)
{
// Yes, replace the value...
PDFIO_DEBUG("_pdfioDictSetValue: Replacing existing value.\n");
pair->value = *value;
return (true);
}
@ -748,13 +749,16 @@ _pdfioDictSetValue(
if (dict->num_pairs >= dict->alloc_pairs)
{
// Expand the dictionary...
_pdfio_pair_t *temp = (_pdfio_pair_t *)realloc(dict->pairs, (dict->alloc_pairs + 16) * sizeof(_pdfio_pair_t));
_pdfio_pair_t *temp = (_pdfio_pair_t *)realloc(dict->pairs, (dict->alloc_pairs + 8) * sizeof(_pdfio_pair_t));
if (!temp)
{
PDFIO_DEBUG("_pdfioDictSetValue: Out of memory.\n");
return (false);
}
dict->pairs = temp;
dict->alloc_pairs += 16;
dict->alloc_pairs += 8;
}
pair = dict->pairs + dict->num_pairs;
@ -764,7 +768,7 @@ _pdfioDictSetValue(
pair->value = *value;
// Re-sort the dictionary and return...
if (dict->num_pairs > 1)
if (dict->num_pairs > 1 && compare_pairs(pair - 1, pair) > 0)
qsort(dict->pairs, dict->num_pairs, sizeof(_pdfio_pair_t), (int (*)(const void *, const void *))compare_pairs);
#ifdef DEBUG
@ -802,11 +806,11 @@ _pdfioDictWrite(pdfio_dict_t *dict, // I - Dictionary
if (!_pdfioFilePrintf(pdf, "/%s", pair->key))
return (false);
if (length && !strcmp(pair->key, "Length"))
if (length && !strcmp(pair->key, "Length") && pair->value.type == PDFIO_VALTYPE_NUMBER && pair->value.value.number <= 0.0f)
{
// Writing an object dictionary with an undefined length
*length = _pdfioFileTell(pdf);
if (!_pdfioFilePuts(pdf, " 999999999"))
if (!_pdfioFilePuts(pdf, " 9999999999"))
return (false);
}
else if (!_pdfioValueWrite(pdf, &pair->value))

View File

@ -22,7 +22,7 @@ static int compare_strings(char **a, char **b);
//
// 'pdfioStringCreate()' - Create a literal string.
// 'pdfioStringCreate()' - Create a durable literal string.
//
// This function creates a literal string associated with the PDF file
// "pwg". The "s" string points to a nul-terminated C string.
@ -31,12 +31,13 @@ static int compare_strings(char **a, char **b);
// `pdfioFileClose` is called.
//
char * // O - New string or `NULL` on error
char * // O - Durable string pointer or `NULL` on error
pdfioStringCreate(
pdfio_file_t *pdf, // I - PDF file
const char *s) // I - Nul-terminated string
{
char *news; // New string
char **match; // Matching string
PDFIO_DEBUG("pdfioStringCreate(pdf=%p, s=\"%s\")\n", pdf, s);
@ -46,8 +47,8 @@ pdfioStringCreate(
return (NULL);
// See if the string has already been added...
if (pdf->num_strings > 0 && (news = (char *)bsearch(&s, pdf->strings, pdf->num_strings, sizeof(char *), (int (*)(const void *, const void *))compare_strings)) != NULL)
return (news);
if (pdf->num_strings > 0 && (match = (char **)bsearch(&s, pdf->strings, pdf->num_strings, sizeof(char *), (int (*)(const void *, const void *))compare_strings)) != NULL)
return (*match);
// Not already added, so add it...
if ((news = strdup(s)) == NULL)
@ -56,7 +57,7 @@ pdfioStringCreate(
if (pdf->num_strings >= pdf->alloc_strings)
{
// Expand the string array...
char **temp = (char **)realloc(pdf->strings, (pdf->alloc_strings + 32) * sizeof(char *));
char **temp = (char **)realloc(pdf->strings, (pdf->alloc_strings + 128) * sizeof(char *));
if (!temp)
{
@ -65,7 +66,7 @@ pdfioStringCreate(
}
pdf->strings = temp;
pdf->alloc_strings += 32;
pdf->alloc_strings += 128;
}
// TODO: Change to insertion sort as needed...
@ -89,7 +90,7 @@ pdfioStringCreate(
//
// 'pdfioStringCreatef()' - Create a formatted string.
// 'pdfioStringCreatef()' - Create a durable formatted string.
//
// This function creates a formatted string associated with the PDF file
// "pwg". The "format" string contains `printf`-style format characters.
@ -98,7 +99,7 @@ pdfioStringCreate(
// `pdfioFileClose` is called.
//
char * // O - New string or `NULL` on error
char * // O - Durable string pointer or `NULL` on error
pdfioStringCreatef(
pdfio_file_t *pdf, // I - PDF file
const char *format, // I - `printf`-style format string

View File

@ -65,6 +65,23 @@ main(int argc, // I - Number of command-line arguments
case PDFIO_VALTYPE_INDIRECT :
printf(" /%s %u %u R\n", pair->key, (unsigned)pair->value.value.indirect.number, pair->value.value.indirect.generation);
break;
case PDFIO_VALTYPE_NAME :
printf(" /%s /%s\n", pair->key, pair->value.value.name);
break;
case PDFIO_VALTYPE_STRING :
printf(" /%s (%s)\n", pair->key, pair->value.value.string);
break;
case PDFIO_VALTYPE_BINARY :
{
size_t bn;
unsigned char *bptr;
printf(" /%s <", pair->key);
for (bn = pair->value.value.binary.datalen, bptr = pair->value.value.binary.data; bn > 0; bn --, bptr ++)
printf("%02X", *bptr);
puts(">");
}
break;
case PDFIO_VALTYPE_NUMBER :
printf(" /%s %g\n", pair->key, pair->value.value.number);
break;