texlive[56266] Build/source/texk/dvipdfm-x: Avoid deref-ing an

commits+kakuto at tug.org commits+kakuto at tug.org
Sat Sep 5 00:48:15 CEST 2020


Revision: 56266
          http://tug.org/svn/texlive?view=revision&revision=56266
Author:   kakuto
Date:     2020-09-05 00:48:15 +0200 (Sat, 05 Sep 2020)
Log Message:
-----------
Avoid deref-ing an already released object. (S. Hirata)

Modified Paths:
--------------
    trunk/Build/source/texk/dvipdfm-x/ChangeLog
    trunk/Build/source/texk/dvipdfm-x/pdfdoc.c
    trunk/Build/source/texk/dvipdfm-x/pdfobj.c

Modified: trunk/Build/source/texk/dvipdfm-x/ChangeLog
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/ChangeLog	2020-09-04 21:36:59 UTC (rev 56265)
+++ trunk/Build/source/texk/dvipdfm-x/ChangeLog	2020-09-04 22:48:15 UTC (rev 56266)
@@ -4,6 +4,10 @@
 	indirect object (object reference) is used for a resource
 	dictionary entry in pdf:put command. The content of an already
 	existing resource dictionary is copied to the new dictionary.
+	* pdfobj.c, pdfdoc.c: pdf_indirect stores a pointer to the
+	object itself but there is no way to know if the object is
+	released. This can result in using junk pointers. To resolve
+	this issue, a list is added to record released indirect objects.
 	* configure.ac: Version 20200905.
 
 2020-09-02  Shunsaku Hirata  <shunsaku.hirata74 at gmail.com>

Modified: trunk/Build/source/texk/dvipdfm-x/pdfdoc.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfdoc.c	2020-09-04 21:36:59 UTC (rev 56265)
+++ trunk/Build/source/texk/dvipdfm-x/pdfdoc.c	2020-09-04 22:48:15 UTC (rev 56266)
@@ -513,7 +513,11 @@
     pdf_add_dict(res_dict, pdf_new_name(category), resources);
   } else if (pdf_obj_typeof(resources) == PDF_INDIRECT) {
     resources = pdf_deref_obj(resources); /* FIXME: deref_obj increment link count */
-    pdf_release_obj(resources); /* FIXME: just to decrement link count */
+    if (!resources) {
+      WARN("Resource %s already released?", category);
+    } else {
+      pdf_release_obj(resources); /* FIXME: just to decrement link count */
+    }
   }
 
   return resources;
@@ -528,6 +532,10 @@
   pdf_obj *duplicate;
 
   resources = pdf_doc_get_page_resources(p, category);
+  if (!resources) {
+    WARN("Can't add object to resource %s", category);
+    return;
+  }
   duplicate = pdf_lookup_dict(resources, resource_name);
   if (duplicate) {
     if (pdf_compare_reference(duplicate, resource_ref)) {

Modified: trunk/Build/source/texk/dvipdfm-x/pdfobj.c
===================================================================
--- trunk/Build/source/texk/dvipdfm-x/pdfobj.c	2020-09-04 21:36:59 UTC (rev 56265)
+++ trunk/Build/source/texk/dvipdfm-x/pdfobj.c	2020-09-04 22:48:15 UTC (rev 56266)
@@ -231,6 +231,8 @@
   pdf_obj      *xref_stream;
   pdf_obj      *output_stream;
   pdf_obj      *current_objstm;
+
+  char         *free_list; /* 8192bytes each bit representing if the object is freed */
 };
 
 #if defined(LIBDPX)
@@ -284,11 +286,16 @@
   p->xref_stream    = NULL;
   p->output_stream  = NULL;
   p->current_objstm = NULL;
+
+  p->free_list = NEW(8192, char);
+  memset(p->free_list, 0, 8192);
 }
 
 static void
 clean_pdf_out_struct (pdf_out *p)
 {
+  if (p->free_list)
+    RELEASE(p->free_list);
   memset(p, 0, sizeof(pdf_out));
 }
 
@@ -3197,6 +3204,8 @@
   pdf_release_obj(objstm);
 }
 
+#define is_free(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8))))
+
 void
 pdf_release_obj (pdf_obj *object)
 {
@@ -3221,23 +3230,26 @@
      * Nothing is using this object so it's okay to remove it.
      * Nonzero "label" means object needs to be written before it's destroyed.
      */
-    if (object->label && p->output.file != NULL) {
-      if (!p->options.use_objstm || object->flags & OBJ_NO_OBJSTM ||
-          (p->options.enable_encrypt && (object->flags & OBJ_NO_ENCRYPT)) ||
-          object->generation)
-        pdf_flush_obj(p, object);
-      else {
-        if (!p->current_objstm) {
-          int *data = NEW(2*OBJSTM_MAX_OBJS+2, int);
-          data[0] = data[1] = 0;
-          p->current_objstm = pdf_new_stream(STREAM_COMPRESS);
-          set_objstm_data(p->current_objstm, data);
-          pdf_label_obj(p, p->current_objstm);
+    if (object->label) {
+      p->free_list[object->label/8] |= (1 << (7-(object->label % 8)));
+      if (p->output.file != NULL) {
+        if (!p->options.use_objstm || object->flags & OBJ_NO_OBJSTM ||
+            (p->options.enable_encrypt && (object->flags & OBJ_NO_ENCRYPT)) ||
+            object->generation) {
+          pdf_flush_obj(p, object);
+        } else {
+          if (!p->current_objstm) {
+            int *data = NEW(2*OBJSTM_MAX_OBJS+2, int);
+            data[0] = data[1] = 0;
+            p->current_objstm = pdf_new_stream(STREAM_COMPRESS);
+            set_objstm_data(p->current_objstm, data);
+            pdf_label_obj(p, p->current_objstm);
+          }
+          if (pdf_add_objstm(p, p->current_objstm, object) == OBJSTM_MAX_OBJS) {
+            release_objstm(p->current_objstm);
+            p->current_objstm = NULL;
+          }
         }
-        if (pdf_add_objstm(p, p->current_objstm, object) == OBJSTM_MAX_OBJS) {
-          release_objstm(p->current_objstm);
-          p->current_objstm = NULL;
-        }
       }
     }
     switch (object->type) {
@@ -3681,12 +3693,20 @@
       pdf_release_obj(obj);
       obj = pdf_get_object(pf, obj_num, obj_gen);
     } else {
-      pdf_obj *next_obj = OBJ_OBJ(obj);
-      if (!next_obj) {
-        ERROR("Undefined object reference"); 
+      pdf_out      *p    = current_output();
+      pdf_indirect *data = obj->data;
+
+      if ((p->free_list[data->label/8] & (1 << (7-((data->label) % 8))))) {
+        pdf_release_obj(obj);
+        return NULL;
+      } else {
+        pdf_obj *next_obj = OBJ_OBJ(obj);
+        if (!next_obj) {
+          ERROR("Undefined object reference"); 
+        }
+        pdf_release_obj(obj);
+        obj = pdf_link_obj(next_obj);
       }
-      pdf_release_obj(obj);
-      obj = pdf_link_obj(next_obj);
     }
   }
 



More information about the tex-live-commits mailing list.