summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pdf/ghostpdf.c')
-rw-r--r--pdf/ghostpdf.c222
1 files changed, 198 insertions, 24 deletions
diff --git a/pdf/ghostpdf.c b/pdf/ghostpdf.c
index 8d88b090..2dd4c63c 100644
--- a/pdf/ghostpdf.c
+++ b/pdf/ghostpdf.c
@@ -79,10 +79,15 @@ static int pdfi_output_metadata(pdf_context *ctx)
{
int code = 0;
+ if (ctx->filename != NULL)
+ dmprintf2(ctx->memory, "\n %s has %"PRIi64" ", ctx->filename, ctx->num_pages);
+ else
+ dmprintf1(ctx->memory, "\n File has %"PRIi64" ", ctx->num_pages);
+
if (ctx->num_pages > 1)
- dmprintf2(ctx->memory, "\n %s has %"PRIi64" pages\n\n", ctx->filename, ctx->num_pages);
+ dmprintf(ctx->memory, "pages\n\n");
else
- dmprintf2(ctx->memory, "\n %s has %"PRIi64" page.\n\n", ctx->filename, ctx->num_pages);
+ dmprintf(ctx->memory, "page.\n\n");
if (ctx->Info != NULL) {
pdf_name *n = NULL;
@@ -151,6 +156,7 @@ static int pdfi_output_metadata(pdf_context *ctx)
pdfi_countdown(n);
n = NULL;
}
+ dmprintf(ctx->memory, "\n");
return code;
}
@@ -177,7 +183,7 @@ static int pdfi_dump_box(pdf_context *ctx, pdf_dict *page_dict, const char *Key)
if (i != 0)
dmprintf(ctx->memory, " ");
if (code == 0) {
- if (a->values[i]->type == PDF_INT)
+ if (pdfi_type_of(a->values[i]) == PDF_INT)
dmprintf1(ctx->memory, "%"PRIi64"", ((pdf_num *)a->values[i])->value.i);
else
dmprintf1(ctx->memory, "%f", ((pdf_num *)a->values[i])->value.d);
@@ -192,6 +198,90 @@ static int pdfi_dump_box(pdf_context *ctx, pdf_dict *page_dict, const char *Key)
return code;
}
+static int dump_font(pdf_context *ctx, pdf_dict *font_dict, bool space_name)
+{
+ pdf_obj *obj = NULL;
+ char *str = NULL;
+ int len = 0, code = 0, i;
+ bool known = false, type0 = false;
+
+ code = pdfi_dict_get_type(ctx, font_dict, "BaseFont", PDF_NAME, &obj);
+ if (code >= 0) {
+ code = pdfi_string_from_name(ctx, (pdf_name *)obj, &str, &len);
+ if (code >= 0) {
+ dmprintf1(ctx->memory, "%s", str);
+ if (len < 32 && space_name) {
+ for (i = 0; i < 32 - len;i++)
+ dmprintf(ctx->memory, " ");
+ } else
+ dmprintf(ctx->memory, " ");
+ (void)pdfi_free_string_from_name(ctx, str);
+ }
+ pdfi_countdown(obj);
+ obj = NULL;
+ }
+
+ code = pdfi_dict_get_type(ctx, font_dict, "Subtype", PDF_NAME, &obj);
+ if (code >= 0) {
+ code = pdfi_string_from_name(ctx, (pdf_name *)obj, &str, &len);
+ if (code >= 0) {
+ dmprintf1(ctx->memory, "%s", str);
+ for (i = 0; i < 16 - len;i++)
+ dmprintf(ctx->memory, " ");
+ (void)pdfi_free_string_from_name(ctx, str);
+ }
+ if (pdfi_name_is((pdf_name *)obj, "Type0"))
+ type0 = true;
+ pdfi_countdown(obj);
+ obj = NULL;
+ }
+
+ if (!type0) {
+ code = pdfi_dict_get_type(ctx, font_dict, "Embedded", PDF_BOOL, &obj);
+ if (code >= 0) {
+ if (obj == PDF_FALSE_OBJ)
+ dmprintf(ctx->memory, "Not embedded ");
+ else
+ dmprintf(ctx->memory, "Embedded ");
+ pdfi_countdown(obj);
+ obj = NULL;
+ }
+ else
+ dmprintf(ctx->memory, "Not embedded ");
+ } else
+ dmprintf(ctx->memory, " ");
+
+ code = pdfi_dict_get_type(ctx, font_dict, "ToUnicode", PDF_BOOL, &obj);
+ if (code >= 0) {
+ if (obj == PDF_TRUE_OBJ)
+ dmprintf(ctx->memory, "Has ToUnicode ");
+ else
+ dmprintf(ctx->memory, "No ToUnicode ");
+ pdfi_countdown(obj);
+ obj = NULL;
+ }
+ else
+ dmprintf(ctx->memory, "No ToUnicode ");
+
+ code = pdfi_dict_known(ctx, font_dict, "Descendants", &known);
+ if (code >= 0 && known) {
+ code = pdfi_dict_get_type(ctx, font_dict, "Descendants", PDF_ARRAY, &obj);
+ if (code >= 0) {
+ pdf_obj *desc = NULL;
+
+ code = pdfi_array_get_type(ctx, (pdf_array *)obj, 0, PDF_DICT, &desc);
+ if (code >= 0) {
+ dmprintf(ctx->memory, "\n Descendants: [");
+ (void)dump_font(ctx, (pdf_dict *)desc, false);
+ dmprintf(ctx->memory, "]");
+ }
+ pdfi_countdown(obj);
+ obj = NULL;
+ }
+ }
+ return 0;
+}
+
/*
* This routine along with pdfi_output_metadtaa above, dumps certain kinds
* of metadata from the PDF file, and from each page in the PDF file. It is
@@ -202,12 +292,13 @@ static int pdfi_dump_box(pdf_context *ctx, pdf_dict *page_dict, const char *Key)
* we always emit them, and the switches -dDumpFontsNeeded, -dDumpXML,
* -dDumpFontsUsed and -dShowEmbeddedFonts are not implemented at all yet.
*/
-static int pdfi_output_page_info(pdf_context *ctx, uint64_t page_num)
+int pdfi_output_page_info(pdf_context *ctx, uint64_t page_num)
{
int code;
bool known = false;
double f;
pdf_dict *page_dict = NULL;
+ pdf_array *fonts_array = NULL, *spots_array = NULL;
code = pdfi_page_get_dict(ctx, page_num, &page_dict);
if (code < 0)
@@ -271,7 +362,7 @@ static int pdfi_output_page_info(pdf_context *ctx, uint64_t page_num)
return code;
}
- code = pdfi_check_page(ctx, page_dict, false);
+ code = pdfi_check_page(ctx, page_dict, &fonts_array, &spots_array, false);
if (code < 0) {
if (ctx->args.pdfstoponerror)
return code;
@@ -283,16 +374,62 @@ static int pdfi_output_page_info(pdf_context *ctx, uint64_t page_num)
code = pdfi_dict_known(ctx, page_dict, "Annots", &known);
if (code < 0) {
if (code != gs_error_undefined && ctx->args.pdfstoponerror)
- return code;
+ goto error;
} else {
if (known == true)
dmprintf(ctx->memory, " Page contains Annotations");
+ code = 0;
+ }
+
+ if (spots_array != NULL) {
+ uint64_t index = 0;
+ pdf_name *spot = NULL;
+ char *str = NULL;
+ int len;
+
+ dmprintf(ctx->memory, "\n Page Spot colors: \n");
+ for (index = 0;index < pdfi_array_size(spots_array);index++) {
+ code = pdfi_array_get(ctx, spots_array, index, (pdf_obj **)&spot);
+ if (code >= 0) {
+ if (pdfi_type_of(spot) == PDF_NAME) {
+ code = pdfi_string_from_name(ctx, spot, &str, &len);
+ if (code >= 0) {
+ dmprintf1(ctx->memory, " '%s'\n", str);
+ (void)pdfi_free_string_from_name(ctx, str);
+ }
+ }
+ pdfi_countdown(spot);
+ spot = NULL;
+ }
+ }
+ code = 0;
}
+ if (fonts_array != NULL && pdfi_array_size(fonts_array) != 0) {
+ uint64_t index = 0;
+ pdf_dict *font_dict = NULL;
+
+ dmprintf(ctx->memory, "\n Fonts used: \n");
+ for (index = 0;index < pdfi_array_size(fonts_array);index++) {
+ code = pdfi_array_get_type(ctx, fonts_array, index, PDF_DICT, (pdf_obj **)&font_dict);
+ if (code >= 0) {
+ dmprintf(ctx->memory, " ");
+ (void)dump_font(ctx, font_dict, true);
+ dmprintf(ctx->memory, "\n");
+ pdfi_countdown(font_dict);
+ font_dict = NULL;
+ }
+ }
+ code = 0;
+ }
+
+error:
+ pdfi_countdown(fonts_array);
+ pdfi_countdown(spots_array);
dmprintf(ctx->memory, "\n\n");
pdfi_countdown(page_dict);
- return 0;
+ return code;
}
/* Error and warning string tables. There should be a string for each error and warning
@@ -347,6 +484,8 @@ const char *gs_error_strings[] = {
"unregistered",
"invalidcontext",
"invalidid",
+ "pdf_stackoverflow",
+ "circular reference"
};
const char *gs_internal_error_strings[] = {
@@ -358,16 +497,15 @@ const char *gs_internal_error_strings[] = {
"exec stack underflow",
"VMreclaim",
"Need input",
+ "need file",
"No defined error",
"No defined error (2)",
- "need file",
"error info",
"handled",
- "circular reference"
};
-#define LASTNORMALGSERROR gs_error_invalidid * -1
+#define LASTNORMALGSERROR gs_error_circular_reference * -1
#define FIRSTINTERNALERROR gs_error_hit_detected * -1
-#define LASTGSERROR gs_error_circular_reference * -1
+#define LASTGSERROR gs_error_handled * -1
void pdfi_verbose_error(pdf_context *ctx, int gs_error, const char *gs_lib_function, int pdfi_error, const char *pdfi_function_name, const char *extra_info)
{
@@ -784,7 +922,7 @@ int pdfi_prep_collection(pdf_context *ctx, uint64_t *TotalFiles, char ***names_a
if (code < 0)
goto exit;
- if (File->type == PDF_DICT) {
+ if (pdfi_type_of(File) == PDF_DICT) {
if (pdfi_dict_knownget_type(ctx, (pdf_dict *)File, "EF", PDF_DICT, &EF)) {
if (pdfi_dict_knownget_type(ctx, (pdf_dict *)EF, "F", PDF_STREAM, &F)) {
pdf_dict *stream_dict = NULL;
@@ -859,7 +997,7 @@ int pdfi_prep_collection(pdf_context *ctx, uint64_t *TotalFiles, char ***names_a
/* Create an entry for the Description in the names array */
code = pdfi_array_get(ctx, FileNames, ix * 2, (pdf_obj **)&Name);
if (code >= 0) {
- if (Name->type == PDF_STRING) {
+ if (pdfi_type_of((pdf_obj *)Name) == PDF_STRING) {
working_array[(index * 2) + 1] = (char *)gs_alloc_bytes(ctx->memory, Name->length + 3, "Collection file names array entry");
if (working_array[(index * 2) + 1] != NULL) {
memset(working_array[(index * 2) + 1], 0x00, Name->length + 3);
@@ -999,6 +1137,13 @@ int pdfi_process_pdf_file(pdf_context *ctx, char *filename)
else
code = pdfi_process(ctx);
+ /* Pdfmark_InitialPage is the offset for Page Dests in
+ * /Outlines and Link annotations. It is the count of pages
+ * processed so far. Update it by the number of pages in
+ * this file.
+ */
+ ctx->Pdfmark_InitialPage += ctx->num_pages;
+
pdfi_close_pdf_file(ctx);
return code;
}
@@ -1037,9 +1182,14 @@ static int pdfi_init_file(pdf_context *ctx)
if (code < 0 && code != gs_error_undefined)
goto exit;
if (code == 0) {
- code = pdfi_initialise_Decryption(ctx);
- if (code < 0)
- goto exit;
+ if (pdfi_type_of(o) == PDF_DICT) {
+ code = pdfi_initialise_Decryption(ctx);
+ if (code < 0)
+ goto exit;
+ } else {
+ if (pdfi_type_of(o) != PDF_NULL)
+ pdfi_set_error(ctx, code, NULL, E_PDF_BADENCRYPT, "pdfi_init_file", NULL);
+ }
}
}
@@ -1144,6 +1294,7 @@ int pdfi_set_input_stream(pdf_context *ctx, stream *stm)
}
/* Determine file size */
+ pdfi_seek(ctx, ctx->main_stream, 0, SEEK_SET);
pdfi_seek(ctx, ctx->main_stream, 0, SEEK_END);
ctx->main_stream_length = pdfi_tell(ctx->main_stream);
Offset = BUF_SIZE;
@@ -1268,8 +1419,15 @@ int pdfi_set_input_stream(pdf_context *ctx, stream *stm)
*/
if (last_lineend) {
leftover = last_lineend - Buffer;
- memmove(Buffer + bytes - leftover, last_lineend, leftover);
- bytes -= leftover;
+ /* Ensure we don't try to copy more than half a buffer, because that will
+ * end up overrunning the buffer end. Since we are only doing this to
+ * ensure we don't drop a partial 'startxref' that's far more than enough.
+ */
+ if (leftover < BUF_SIZE / 2) {
+ memmove(Buffer + bytes - leftover, last_lineend, leftover);
+ bytes -= leftover;
+ } else
+ leftover = 0;
} else
leftover = 0;
}
@@ -1757,6 +1915,15 @@ int pdfi_clear_context(pdf_context *ctx)
dmprintf1(ctx->memory, "Normal object cache hit rate: %f\n", hit_rate);
dmprintf1(ctx->memory, "Compressed object cache hit rate: %f\n", compressed_hit_rate);
#endif
+ if (ctx->PathSegments != NULL) {
+ gs_free_object(ctx->memory, ctx->PathSegments, "pdfi_clear_context");
+ ctx->PathSegments = NULL;
+ }
+ if (ctx->PathPts != NULL) {
+ gs_free_object(ctx->memory, ctx->PathPts, "pdfi_clear_context");
+ ctx->PathPts = NULL;
+ }
+
if (ctx->args.PageList) {
gs_free_object(ctx->memory, ctx->args.PageList, "pdfi_clear_context");
ctx->args.PageList = NULL;
@@ -1786,14 +1953,19 @@ int pdfi_clear_context(pdf_context *ctx)
ctx->PagesTree = NULL;
}
- if (ctx->args.cidsubstpath.data != NULL) {
- gs_free_object(ctx->memory, ctx->args.cidsubstpath.data, "cidsubstpath.data");
- ctx->args.cidsubstpath.data = NULL;
+ if (ctx->args.cidfsubstpath.data != NULL) {
+ gs_free_object(ctx->memory, ctx->args.cidfsubstpath.data, "cidfsubstpath.data");
+ ctx->args.cidfsubstpath.data = NULL;
+ }
+
+ if (ctx->args.cidfsubstfont.data != NULL) {
+ gs_free_object(ctx->memory, ctx->args.cidfsubstfont.data, "cidfsubstfont.data");
+ ctx->args.cidfsubstfont.data = NULL;
}
- if (ctx->args.cidsubstfont.data != NULL) {
- gs_free_object(ctx->memory, ctx->args.cidsubstfont.data, "cidsubstpath.data");
- ctx->args.cidsubstfont.data = NULL;
+ if (ctx->args.defaultfont.data != NULL) {
+ gs_free_object(ctx->memory, ctx->args.defaultfont.data, "cidfsubstfont.data");
+ ctx->args.defaultfont.data = NULL;
}
pdfi_free_cstring_array(ctx, &ctx->args.showannottypes);
@@ -1923,6 +2095,8 @@ int pdfi_clear_context(pdf_context *ctx)
ctx->pdffontmap = NULL;
pdfi_countdown(ctx->pdfnativefontmap);
ctx->pdfnativefontmap = NULL;
+ pdfi_countdown(ctx->pdf_substitute_fonts);
+ ctx->pdf_substitute_fonts = NULL;
return 0;
}