diff --git a/CHANGES.md b/CHANGES.md index ab8ad7c..68c11d0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,8 @@ v1.1.0 (Month DD, YYYY) - Added `pdfioFileCreateTemporary` function (Issue #29) - Added `pdfioDictIterateKeys` function (Issue #31) - Added `pdfioContentPathEnd` function. +- Added protection against opening multiple streams in the same file at the + same time. - Fixed "install-shared" target (Issue #32) - Fixed `pdfioContentMatrixRotate` function. diff --git a/pdfio-object.c b/pdfio-object.c index d919982..6053518 100644 --- a/pdfio-object.c +++ b/pdfio-object.c @@ -1,7 +1,7 @@ // // PDF object functions for PDFio. // -// Copyright © 2021 by Michael R Sweet. +// Copyright © 2021-2022 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. @@ -33,8 +33,14 @@ pdfioObjClose(pdfio_obj_t *obj) // I - Object if (!obj) return (false); + // Clear the current object pointer... + obj->pdf->current_obj = NULL; + if (obj->pdf->mode != _PDFIO_MODE_WRITE) - return (true); // Nothing to do when reading + { + // Nothing to do when reading + return (true); + } // Write what remains for the object... if (!obj->offset) @@ -165,6 +171,12 @@ pdfioObjCreateStream( return (NULL); } + if (obj->pdf->current_obj) + { + _pdfioFileError(obj->pdf, "Another object (%u) is already open.", (unsigned)obj->pdf->current_obj->number); + return (NULL); + } + // Write the header... if (!_pdfioDictGetValue(obj->value.value.dict, "Length")) { @@ -193,7 +205,8 @@ pdfioObjCreateStream( if (!_pdfioFilePuts(obj->pdf, "stream\n")) return (NULL); - obj->stream_offset = _pdfioFileTell(obj->pdf); + obj->stream_offset = _pdfioFileTell(obj->pdf); + obj->pdf->current_obj = obj; // Return the new stream... return (_pdfioStreamCreate(obj, length_obj, filter)); @@ -454,6 +467,12 @@ pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object if (!obj) return (NULL); + if (obj->pdf->current_obj) + { + _pdfioFileError(obj->pdf, "Another object (%u) is already open.", (unsigned)obj->pdf->current_obj->number); + return (NULL); + } + // Make sure we've loaded the object dictionary... if (!obj->value.type) { @@ -466,6 +485,8 @@ pdfioObjOpenStream(pdfio_obj_t *obj, // I - Object return (NULL); // Open the stream... + obj->pdf->current_obj = obj; + return (_pdfioStreamOpen(obj, decode)); } diff --git a/pdfio-private.h b/pdfio-private.h index 9c59c75..cc6bf63 100644 --- a/pdfio-private.h +++ b/pdfio-private.h @@ -1,7 +1,7 @@ // // Private header file for PDFio. // -// Copyright © 2021 by Michael R Sweet. +// Copyright © 2021-2022 by Michael R Sweet. // // Licensed under Apache License v2.0. See the file "LICENSE" for more // information. @@ -289,7 +289,8 @@ struct _pdfio_file_s // PDF file structure pdfio_dict_t **dicts; // Dictionaries size_t num_objs, // Number of objects alloc_objs; // Allocated objects - pdfio_obj_t **objs; // Objects + pdfio_obj_t **objs, // Objects + *current_obj; // Current object being written/read size_t num_objmaps, // Number of object maps alloc_objmaps; // Allocated object maps _pdfio_objmap_t *objmaps; // Object maps diff --git a/pdfio-stream.c b/pdfio-stream.c index 7e35652..5fd54cc 100644 --- a/pdfio-stream.c +++ b/pdfio-stream.c @@ -174,6 +174,8 @@ pdfioStreamClose(pdfio_stream_t *st) // I - Stream done: + st->pdf->current_obj = NULL; + free(st->prbuffer); free(st->psbuffer); free(st); diff --git a/testpdfio.c b/testpdfio.c index d17c803..61f39c6 100644 --- a/testpdfio.c +++ b/testpdfio.c @@ -3239,13 +3239,13 @@ write_unit_file( // Create some image objects... fputs("pdfioFileCreateImageObjFromFile(\"testfiles/color.jpg\"): ", stdout); if ((color_jpg = pdfioFileCreateImageObjFromFile(outpdf, "testfiles/color.jpg", true)) != NULL) - puts("PASS"); + printf("PASS (%u)\n", (unsigned)pdfioObjGetNumber(color_jpg)); else return (1); fputs("pdfioFileCreateImageObjFromFile(\"testfiles/gray.jpg\"): ", stdout); if ((gray_jpg = pdfioFileCreateImageObjFromFile(outpdf, "testfiles/gray.jpg", true)) != NULL) - puts("PASS"); + printf("PASS (%u)\n", (unsigned)pdfioObjGetNumber(gray_jpg)); else return (1);