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) 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... // Yes, replace the value...
PDFIO_DEBUG("_pdfioDictSetValue: Replacing existing value.\n");
pair->value = *value; pair->value = *value;
return (true); return (true);
} }
@ -748,13 +749,16 @@ _pdfioDictSetValue(
if (dict->num_pairs >= dict->alloc_pairs) if (dict->num_pairs >= dict->alloc_pairs)
{ {
// Expand the dictionary... // 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) if (!temp)
{
PDFIO_DEBUG("_pdfioDictSetValue: Out of memory.\n");
return (false); return (false);
}
dict->pairs = temp; dict->pairs = temp;
dict->alloc_pairs += 16; dict->alloc_pairs += 8;
} }
pair = dict->pairs + dict->num_pairs; pair = dict->pairs + dict->num_pairs;
@ -764,7 +768,7 @@ _pdfioDictSetValue(
pair->value = *value; pair->value = *value;
// Re-sort the dictionary and return... // 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); qsort(dict->pairs, dict->num_pairs, sizeof(_pdfio_pair_t), (int (*)(const void *, const void *))compare_pairs);
#ifdef DEBUG #ifdef DEBUG
@ -802,11 +806,11 @@ _pdfioDictWrite(pdfio_dict_t *dict, // I - Dictionary
if (!_pdfioFilePrintf(pdf, "/%s", pair->key)) if (!_pdfioFilePrintf(pdf, "/%s", pair->key))
return (false); 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 // Writing an object dictionary with an undefined length
*length = _pdfioFileTell(pdf); *length = _pdfioFileTell(pdf);
if (!_pdfioFilePuts(pdf, " 999999999")) if (!_pdfioFilePuts(pdf, " 9999999999"))
return (false); return (false);
} }
else if (!_pdfioValueWrite(pdf, &pair->value)) 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 // This function creates a literal string associated with the PDF file
// "pwg". The "s" string points to a nul-terminated C string. // "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. // `pdfioFileClose` is called.
// //
char * // O - New string or `NULL` on error char * // O - Durable string pointer or `NULL` on error
pdfioStringCreate( pdfioStringCreate(
pdfio_file_t *pdf, // I - PDF file pdfio_file_t *pdf, // I - PDF file
const char *s) // I - Nul-terminated string const char *s) // I - Nul-terminated string
{ {
char *news; // New string char *news; // New string
char **match; // Matching string
PDFIO_DEBUG("pdfioStringCreate(pdf=%p, s=\"%s\")\n", pdf, s); PDFIO_DEBUG("pdfioStringCreate(pdf=%p, s=\"%s\")\n", pdf, s);
@ -46,8 +47,8 @@ pdfioStringCreate(
return (NULL); return (NULL);
// See if the string has already been added... // 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) 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 (news); return (*match);
// Not already added, so add it... // Not already added, so add it...
if ((news = strdup(s)) == NULL) if ((news = strdup(s)) == NULL)
@ -56,7 +57,7 @@ pdfioStringCreate(
if (pdf->num_strings >= pdf->alloc_strings) if (pdf->num_strings >= pdf->alloc_strings)
{ {
// Expand the string array... // 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) if (!temp)
{ {
@ -65,7 +66,7 @@ pdfioStringCreate(
} }
pdf->strings = temp; pdf->strings = temp;
pdf->alloc_strings += 32; pdf->alloc_strings += 128;
} }
// TODO: Change to insertion sort as needed... // 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 // This function creates a formatted string associated with the PDF file
// "pwg". The "format" string contains `printf`-style format characters. // "pwg". The "format" string contains `printf`-style format characters.
@ -98,7 +99,7 @@ pdfioStringCreate(
// `pdfioFileClose` is called. // `pdfioFileClose` is called.
// //
char * // O - New string or `NULL` on error char * // O - Durable string pointer or `NULL` on error
pdfioStringCreatef( pdfioStringCreatef(
pdfio_file_t *pdf, // I - PDF file pdfio_file_t *pdf, // I - PDF file
const char *format, // I - `printf`-style format string 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 : case PDFIO_VALTYPE_INDIRECT :
printf(" /%s %u %u R\n", pair->key, (unsigned)pair->value.value.indirect.number, pair->value.value.indirect.generation); printf(" /%s %u %u R\n", pair->key, (unsigned)pair->value.value.indirect.number, pair->value.value.indirect.generation);
break; 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 : case PDFIO_VALTYPE_NUMBER :
printf(" /%s %g\n", pair->key, pair->value.value.number); printf(" /%s %g\n", pair->key, pair->value.value.number);
break; break;