summaryrefslogtreecommitdiff
path: root/Build/source
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-09-04 22:48:15 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-09-04 22:48:15 +0000
commite62d1afec0e9e81971e4f6941a5abbc5c22e8b1f (patch)
treecefd93e0b060f502307f276b6872415821ae2a53 /Build/source
parent14dafc8d65c0e21fd9ea523c74d6d7a265edcb18 (diff)
Avoid deref-ing an already released object. (S. Hirata)
git-svn-id: svn://tug.org/texlive/trunk@56266 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source')
-rw-r--r--Build/source/texk/dvipdfm-x/ChangeLog4
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdoc.c10
-rw-r--r--Build/source/texk/dvipdfm-x/pdfobj.c62
3 files changed, 54 insertions, 22 deletions
diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog
index f4197108dbd..31948578624 100644
--- a/Build/source/texk/dvipdfm-x/ChangeLog
+++ b/Build/source/texk/dvipdfm-x/ChangeLog
@@ -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@gmail.com>
diff --git a/Build/source/texk/dvipdfm-x/pdfdoc.c b/Build/source/texk/dvipdfm-x/pdfdoc.c
index 443b537818a..a4e96026c8a 100644
--- a/Build/source/texk/dvipdfm-x/pdfdoc.c
+++ b/Build/source/texk/dvipdfm-x/pdfdoc.c
@@ -513,7 +513,11 @@ pdf_doc_get_page_resources (pdf_doc *p, const char *category)
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_doc_add_page_resource (const char *category,
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)) {
diff --git a/Build/source/texk/dvipdfm-x/pdfobj.c b/Build/source/texk/dvipdfm-x/pdfobj.c
index 6c90ad861a8..76f2155ec15 100644
--- a/Build/source/texk/dvipdfm-x/pdfobj.c
+++ b/Build/source/texk/dvipdfm-x/pdfobj.c
@@ -231,6 +231,8 @@ struct pdf_out {
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 @@ init_pdf_out_struct (pdf_out *p)
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 @@ release_objstm (pdf_obj *objstm)
pdf_release_obj(objstm);
}
+#define is_free(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8))))
+
void
pdf_release_obj (pdf_obj *object)
{
@@ -3221,22 +3230,25 @@ pdf_release_obj (pdf_obj *object)
* 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 (pdf_add_objstm(p, p->current_objstm, object) == OBJSTM_MAX_OBJS) {
- release_objstm(p->current_objstm);
- p->current_objstm = NULL;
+ 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;
+ }
}
}
}
@@ -3681,12 +3693,20 @@ pdf_deref_obj (pdf_obj *obj)
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);
}
}