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.