[gs-cvs] rev 7637 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Tue Jan 23 05:42:42 PST 2007


Author: leonardo
Date: 2007-01-23 05:42:42 -0800 (Tue, 23 Jan 2007)
New Revision: 7637

Modified:
   trunk/gs/src/gdevpdf.c
   trunk/gs/src/gdevpdfm.c
   trunk/gs/src/imain.c
Log:
Fix (pdfwrite) : A crash when /OUT pdfmark refers to undefined node.

DETAILS :

Bug 688927 "ps2pdf segfaults on inconsistent subordinate Count parameter in bookmark pdfmarks".

The test document is incorrect, but we must not crash with it.

1. Inserted a check into pdfmark_write_outline.
2. Propagated error code from pdfmark_write_outline.
3. With the test case an error message contained a wrong device name (imain.c).

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gdevpdf.c
===================================================================
--- trunk/gs/src/gdevpdf.c	2007-01-22 23:23:20 UTC (rev 7636)
+++ trunk/gs/src/gdevpdf.c	2007-01-23 13:42:42 UTC (rev 7637)
@@ -1138,9 +1138,14 @@
 
     if (pdev->outlines_id != 0) {
 	/* depth > 0 is only possible for an incomplete outline tree. */
-	while (pdev->outline_depth > 0)
-	    pdfmark_close_outline(pdev);
-	pdfmark_close_outline(pdev);
+	while (pdev->outline_depth > 0) {
+	    code1 = pdfmark_close_outline(pdev);
+	    if (code >= 0)
+		code = code1;
+	}
+	code = pdfmark_close_outline(pdev);
+	if (code >= 0)
+	    code = code1;
 	pdf_open_obj(pdev, pdev->outlines_id);
 	pprintd1(s, "<< /Count %d", pdev->outlines_open);
 	pprintld2(s, " /First %ld 0 R /Last %ld 0 R >>\n",

Modified: trunk/gs/src/gdevpdfm.c
===================================================================
--- trunk/gs/src/gdevpdfm.c	2007-01-22 23:23:20 UTC (rev 7636)
+++ trunk/gs/src/gdevpdfm.c	2007-01-23 13:42:42 UTC (rev 7637)
@@ -755,12 +755,19 @@
 		      long next_id)
 {
     stream *s;
+    int code = 0;
 
     pdf_open_separate(pdev, pnode->id);
-    pnode->action->id = pnode->id;
+    if (pnode->action != NULL)
+	pnode->action->id = pnode->id;
+    else {
+	eprintf1("pdfmark error: Outline node %d has no action or destination.\n", pnode->id);
+	code = gs_note_error(gs_error_undefined);
+    }
     s = pdev->strm;
     stream_puts(s, "<< ");
-    cos_dict_elements_write(pnode->action, pdev);
+    if (pnode->action != NULL)
+	cos_dict_elements_write(pnode->action, pdev);
     if (pnode->count)
 	pprintd1(s, "/Count %d ", pnode->count);
     pprintld1(s, "/Parent %ld 0 R\n", pnode->parent_id);
@@ -773,9 +780,10 @@
 		  pnode->first_id, pnode->last_id);
     stream_puts(s, ">>\n");
     pdf_end_separate(pdev);
-    COS_FREE(pnode->action, "pdfmark_write_outline");
+    if (pnode->action != NULL)
+	COS_FREE(pnode->action, "pdfmark_write_outline");
     pnode->action = 0;
-    return 0;
+    return code;
 }
 
 /* Adjust the parent's count when writing an outline node. */
@@ -803,12 +811,10 @@
 {
     int depth = pdev->outline_depth;
     pdf_outline_level_t *plevel = &pdev->outline_levels[depth];
-    int code;
+    int code = 0;
 
     if (plevel->last.id) {	/* check for incomplete tree */
 	code = pdfmark_write_outline(pdev, &plevel->last, 0);
-	if (code < 0)
-	    return code;
     }
     if (depth > 0) {
 	plevel[-1].last.last_id = plevel->last.id;
@@ -818,7 +824,7 @@
 	    pdev->closed_outline_depth--;
 	pdev->outline_depth--;
     }
-    return 0;
+    return code;
 }
 
 /* OUT pdfmark */

Modified: trunk/gs/src/imain.c
===================================================================
--- trunk/gs/src/imain.c	2007-01-22 23:23:20 UTC (rev 7636)
+++ trunk/gs/src/imain.c	2007-01-23 13:42:42 UTC (rev 7637)
@@ -760,6 +760,7 @@
 #ifndef PSI_INCLUDED
 	if (i_ctx_p->pgs != NULL && i_ctx_p->pgs->device != NULL) {
 	    gx_device *pdev = i_ctx_p->pgs->device;
+	    const char * dname = pdev->dname;
 
 	    /* make sure device doesn't isn't freed by .uninstalldevice */
 	    rc_adjust(pdev, 1, "gs_main_finit");	
@@ -772,7 +773,7 @@
 	    code = gs_closedevice(pdev);
 	    if (code < 0)
 		eprintf2("ERROR %d closing %s device. See gs/src/ierrors.h for code explanation.\n",
-		    code, i_ctx_p->pgs->device->dname);
+		    code, dname);
 	    rc_decrement(pdev, "gs_main_finit");		/* device might be freed */
 	    if (exit_status == 0 || exit_status == e_Quit)
 		exit_status = code;



More information about the gs-cvs mailing list