Skip to content

Commit

Permalink
Fix #2556
Browse files Browse the repository at this point in the history
Immunize against wrong path specifications by checking whether the current path dictionary actually exists.
  • Loading branch information
JorjMcKie committed Sep 19, 2023
1 parent 4809847 commit 8669ed7
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 2 deletions.
8 changes: 7 additions & 1 deletion fitz/helper-devices.i
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ jm_lineart_path(fz_context *ctx, jm_lineart_device *dev, const fz_path *path)
DICT_SETITEM_DROP(dev_pathdict, dictkey_items, PyList_New(0));
fz_walk_path(ctx, path, &trace_path_walker, dev);
// Check if any items were added ...
if (!PyList_Size(PyDict_GetItem(dev_pathdict, dictkey_items))) {
if (!PyDict_GetItem(dev_pathdict, dictkey_items) || !PyList_Size(PyDict_GetItem(dev_pathdict, dictkey_items))) {
Py_CLEAR(dev_pathdict);
}
}
Expand Down Expand Up @@ -468,6 +468,9 @@ jm_lineart_clip_path(fz_context *ctx, fz_device *dev_, const fz_path *path, int
trace_device_ctm = ctm; //fz_concat(ctm, trace_device_ptm);
path_type = CLIP_PATH;
jm_lineart_path(ctx, dev, path);
if (!dev_pathdict) {
return;
}
DICT_SETITEM_DROP(dev_pathdict, dictkey_type, PyUnicode_FromString("clip"));
DICT_SETITEMSTR_DROP(dev_pathdict, "even_odd", JM_BOOL(even_odd));
if (!PyDict_GetItemString(dev_pathdict, "closePath")) {
Expand All @@ -489,6 +492,9 @@ jm_lineart_clip_stroke_path(fz_context *ctx, fz_device *dev_, const fz_path *pat
trace_device_ctm = ctm; //fz_concat(ctm, trace_device_ptm);
path_type = CLIP_STROKE_PATH;
jm_lineart_path(ctx, dev, path);
if (!dev_pathdict) {
return;
}
DICT_SETITEM_DROP(dev_pathdict, dictkey_type, PyUnicode_FromString("clip"));
DICT_SETITEMSTR_DROP(dev_pathdict, "even_odd", Py_BuildValue("s", NULL));
if (!PyDict_GetItemString(dev_pathdict, "closePath")) {
Expand Down
4 changes: 4 additions & 0 deletions src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18315,6 +18315,8 @@ def jm_lineart_clip_path(dev, ctx, path, even_odd, ctm, scissor):
dev.ctm = mupdf.FzMatrix(ctm) # fz_concat(ctm, trace_device_ptm);
dev.path_type = trace_device_CLIP_PATH
jm_lineart_path(dev, ctx, path)
if dev.pathdict is None:
return
dev.pathdict[ dictkey_type] = 'clip'
dev.pathdict[ 'even_odd'] = bool(even_odd)
if 'closePath' not in dev.pathdict:
Expand All @@ -18335,6 +18337,8 @@ def jm_lineart_clip_stroke_path(dev, ctx, path, stroke, ctm, scissor):
dev.ctm = mupdf.FzMatrix(ctm) # fz_concat(ctm, trace_device_ptm);
dev.path_type = trace_device_CLIP_STROKE_PATH
jm_lineart_path(dev, ctx, path)
if dev.pathdict is None:
return
dev.pathdict['dictkey_type'] = 'clip'
dev.pathdict['even_odd'] = None
if 'closePath' not in dev.pathdict:
Expand Down
8 changes: 7 additions & 1 deletion src/extra.i
Original file line number Diff line number Diff line change
Expand Up @@ -2850,7 +2850,7 @@ jm_lineart_path(jm_lineart_device *dev, const fz_path *path)
DICT_SETITEM_DROP(dev->pathdict, dictkey_items, PyList_New(0));
mupdf::ll_fz_walk_path(path, &trace_path_walker, dev);
// Check if any items were added ...
if (!PyList_Size(PyDict_GetItem(dev->pathdict, dictkey_items)))
if (!PyDict_GetItem(dev->pathdict, dictkey_items) || !PyList_Size(PyDict_GetItem(dev->pathdict, dictkey_items)))
{
Py_CLEAR(dev->pathdict);
}
Expand Down Expand Up @@ -3018,6 +3018,9 @@ jm_lineart_clip_path(fz_context *ctx, fz_device *dev_, const fz_path *path, int
dev->ctm = ctm; //fz_concat(ctm, trace_device_ptm);
dev->path_type = CLIP_PATH;
jm_lineart_path(dev, path);
if (!dev->pathdict) {
return;
}
DICT_SETITEM_DROP(dev->pathdict, dictkey_type, PyUnicode_FromString("clip"));
DICT_SETITEMSTR_DROP(dev->pathdict, "even_odd", JM_BOOL(even_odd));
if (!PyDict_GetItemString(dev->pathdict, "closePath")) {
Expand All @@ -3038,6 +3041,9 @@ jm_lineart_clip_stroke_path(fz_context *ctx, fz_device *dev_, const fz_path *pat
dev->ctm = ctm; //fz_concat(ctm, trace_device_ptm);
dev->path_type = CLIP_STROKE_PATH;
jm_lineart_path(dev, path);
if (!dev->pathdict) {
return;
}
DICT_SETITEM_DROP(dev->pathdict, dictkey_type, PyUnicode_FromString("clip"));
DICT_SETITEMSTR_DROP(dev->pathdict, "even_odd", Py_BuildValue("s", NULL));
if (!PyDict_GetItemString(dev->pathdict, "closePath")) {
Expand Down
13 changes: 13 additions & 0 deletions tests/test_drawings.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,16 @@ def test_2462():
doc = fitz.open(f"{scriptdir}/resources/test-2462.pdf")
page = doc[0]
vg = page.get_drawings(extended=True)

def test_2556():
"""Ensure that incomplete clip paths will be properly ignored."""
doc = fitz.open() # new empty PDF
page = doc.new_page() # new page
# following contains an incomplete clip
c = b"q 50 697.6 400 100.0 re W n q 0 0 m W n Q "
xref = doc.get_new_xref() # prepare /Contents object for page
doc.update_object(xref,"<<>>") # new xref now is a dictionary
doc.update_stream(xref, c) # store drawing commands
page.set_contents(xref) # give the page this xref as /Contents
# following will bring down interpreter if fix not installed
assert page.get_drawings(extended=True)

0 comments on commit 8669ed7

Please sign in to comment.