Skip to content

Commit fffe7ef

Browse files
committed
Improve Pixmap error handling
1 parent 17df86b commit fffe7ef

File tree

7 files changed

+108
-63
lines changed

7 files changed

+108
-63
lines changed

fitz/fitz.i

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fz_throw(gctx, FZ_ERROR_GENERIC, msg)
4141
%enddef
4242
//=============================================================================
4343

44-
// SWIG macro: check whether document type is PDF
44+
// SWIG macro: ensure that document type is PDF
4545
%define assert_PDF(cond)
4646
if (!cond) THROWMSG("not a PDF")
4747
%enddef
@@ -116,7 +116,7 @@ struct fz_document_s
116116
fprintf(stderr, " done!\n");
117117
#endif
118118
}
119-
FITZEXCEPTION(fz_document_s, result==NULL)
119+
FITZEXCEPTION(fz_document_s, !result)
120120
%pythonprepend fz_document_s %{
121121
if not filename or type(filename) == str:
122122
pass
@@ -133,9 +133,8 @@ struct fz_document_s
133133
self.metadata = None
134134
self.openErrCode = 0
135135
self.openErrMsg = ''
136-
self._page_refs = weakref.WeakValueDictionary()
137-
138-
%}
136+
self.FontInfos = []
137+
self._page_refs = weakref.WeakValueDictionary()%}
139138
%pythonappend fz_document_s %{
140139
if this:
141140
self.openErrCode = self._getGCTXerrcode()
@@ -151,7 +150,7 @@ struct fz_document_s
151150
{
152151
struct fz_document_s *doc = NULL;
153152
fz_stream *data = NULL;
154-
char *streamdata;
153+
char *streamdata = NULL;
155154
size_t streamlen = 0;
156155
if (PyBytes_Check(stream))
157156
{
@@ -180,8 +179,7 @@ struct fz_document_s
180179
doc = (fz_document *) pdf_create_document(gctx);
181180
}
182181
}
183-
fz_catch(gctx)
184-
return NULL;
182+
fz_catch(gctx) return NULL;
185183
return doc;
186184
}
187185
@@ -1198,7 +1196,8 @@ if sa < 0:
11981196
fontdict = pdf_dict_get_val(gctx, dict, i);
11991197
if (!pdf_is_dict(gctx, fontdict))
12001198
continue; // not a valid font
1201-
long xref = (long) pdf_to_num(gctx, fontdict);
1199+
int xref = pdf_to_num(gctx, fontdict);
1200+
char *ext = fontextension(gctx, pdf, xref);
12021201
long gen = (long) pdf_to_gen(gctx, fontdict);
12031202
subtype = pdf_dict_get(gctx, fontdict, PDF_NAME_Subtype);
12041203
basefont = pdf_dict_get(gctx, fontdict, PDF_NAME_BaseFont);
@@ -1207,7 +1206,7 @@ if sa < 0:
12071206
else
12081207
bname = basefont;
12091208
name = pdf_dict_get_key(gctx, dict, i);
1210-
PyList_Append(fontlist, Py_BuildValue("(i,i,s,s,s)", xref, gen,
1209+
PyList_Append(fontlist, Py_BuildValue("(i,s,s,s,s)", xref, ext,
12111210
pdf_to_name(gctx, subtype),
12121211
pdf_to_name(gctx, bname),
12131212
pdf_to_name(gctx, name)));
@@ -2046,7 +2045,7 @@ fannot._erase()
20462045
//---------------------------------------------------------------------
20472046
// insert font
20482047
//---------------------------------------------------------------------
2049-
FITZEXCEPTION(insertFont, result<0)
2048+
FITZEXCEPTION(insertFont, !result)
20502049
%pythonprepend insertFont %{
20512050
if not self.parent:
20522051
raise RuntimeError("orphaned object: parent is None")
@@ -2147,7 +2146,7 @@ fannot._erase()
21472146
pdf_dict_puts(gctx, fonts, fontname, font_obj);
21482147
pdf_dict_put(gctx, resources, PDF_NAME_Font, fonts);
21492148
}
2150-
fz_catch(gctx) return -1;
2149+
fz_catch(gctx) return NULL;
21512150
return Py_BuildValue("(i, O)", xref, info);
21522151
}
21532152

@@ -2845,6 +2844,11 @@ struct fz_pixmap_s
28452844
#endif
28462845
}
28472846
FITZEXCEPTION(fz_pixmap_s, !result)
2847+
%pythonappend fz_pixmap_s %{
2848+
if this:
2849+
self.thisown = True
2850+
else:
2851+
self.thisown = False%}
28482852
//---------------------------------------------------------------------
28492853
// create empty pixmap with colorspace and IRect
28502854
//---------------------------------------------------------------------
@@ -3011,6 +3015,8 @@ struct fz_pixmap_s
30113015
type = pdf_dict_get(gctx, ref, PDF_NAME_Subtype);
30123016
if (!pdf_name_eq(gctx, type, PDF_NAME_Image))
30133017
THROWMSG("xref not an image");
3018+
if (!pdf_is_stream(gctx, ref))
3019+
THROWMSG("broken PDF: xref is not a stream");
30143020
img = pdf_load_image(gctx, pdf, ref);
30153021
pdf_drop_obj(gctx, ref);
30163022
pix = fz_get_pixmap_from_image(gctx, img, NULL, NULL, NULL, NULL);
@@ -3260,12 +3266,9 @@ struct fz_pixmap_s
32603266
return "fitz.Pixmap(%s, %s, %s)" % ('None', self.irect, self.alpha)%}
32613267
%pythoncode %{
32623268
def __del__(self):
3263-
if getattr(self, "thisown", True):
3264-
try:
3265-
self.__swig_destroy__(self)
3266-
except:
3267-
pass
3269+
if hasattr(self, "this") and self.thisown:
32683270
self.thisown = False
3271+
self.__swig_destroy__(self)
32693272
%}
32703273
}
32713274
};

fitz/fitz.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ class _object:
103103

104104
VersionFitz = "1.11"
105105
VersionBind = "1.11.2"
106-
VersionDate = "2017-11-15 18:16:55"
107-
version = (VersionBind, VersionFitz, "20171115181655")
106+
VersionDate = "2017-11-18 08:05:47"
107+
version = (VersionBind, VersionFitz, "20171118080547")
108108

109109

110110
#------------------------------------------------------------------------------
@@ -377,16 +377,26 @@ def CheckMorph(o):
377377
raise ValueError("invalid morph parameter")
378378
return True
379379

380-
def CheckFont(page, font):
381-
"""Check whether a font reference is in the page's font list and return its xref.
380+
def CheckFont(page, fontname):
381+
"""Return an entry in the page's font list if reference name matches.
382382
"""
383383
fl = page.getFontList()
384-
have_ref = None
384+
refname = None
385385
for f in fl:
386-
if f[4] == font:
387-
have_ref = f
386+
if f[4] == fontname:
387+
refname = f
388388
break
389-
return have_ref
389+
return refname
390+
391+
def CheckFontInfo(doc, xref):
392+
"""Return a font info if present in the document.
393+
"""
394+
fi = None
395+
for f in doc.FontInfo:
396+
if f[0] == xref:
397+
fi = f
398+
break
399+
return fi
390400

391401
class Document(_object):
392402
"""open() - new empty PDF
@@ -419,10 +429,9 @@ def __init__(self, filename=None, stream=None):
419429
self.metadata = None
420430
self.openErrCode = 0
421431
self.openErrMsg = ''
432+
self.FontInfos = []
422433
self._page_refs = weakref.WeakValueDictionary()
423434

424-
425-
426435
this = _fitz.new_Document(filename, stream)
427436
try:
428437
self.this.append(this)
@@ -1552,6 +1561,13 @@ def __init__(self, *args):
15521561
except __builtin__.Exception:
15531562
self.this = this
15541563

1564+
if this:
1565+
self.thisown = True
1566+
else:
1567+
self.thisown = False
1568+
1569+
1570+
15551571
def gammaWith(self, gamma):
15561572
"""gammaWith(self, gamma)"""
15571573
return _fitz.Pixmap_gammaWith(self, gamma)
@@ -1661,12 +1677,9 @@ def __repr__(self):
16611677
return "fitz.Pixmap(%s, %s, %s)" % ('None', self.irect, self.alpha)
16621678

16631679
def __del__(self):
1664-
if getattr(self, "thisown", True):
1665-
try:
1666-
self.__swig_destroy__(self)
1667-
except:
1668-
pass
1680+
if hasattr(self, "this") and self.thisown:
16691681
self.thisown = False
1682+
self.__swig_destroy__(self)
16701683

16711684
Pixmap_swigregister = _fitz.Pixmap_swigregister
16721685
Pixmap_swigregister(Pixmap)

fitz/fitz_wrap.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3994,7 +3994,8 @@ char *fontextension(fz_context *ctx, pdf_document *doc, int num)
39943994
if (!obj)
39953995
{
39963996
pdf_drop_obj(ctx, o);
3997-
fz_throw(ctx, FZ_ERROR_GENERIC, "invalid font - FontDescriptor missing");
3997+
ext = "n/a";
3998+
return ext;
39983999
}
39994000
pdf_drop_obj(ctx, o);
40004001
o = obj;
@@ -4548,7 +4549,7 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
45484549
SWIGINTERN struct fz_document_s *new_fz_document_s(char const *filename,PyObject *stream){
45494550
struct fz_document_s *doc = NULL;
45504551
fz_stream *data = NULL;
4551-
char *streamdata;
4552+
char *streamdata = NULL;
45524553
size_t streamlen = 0;
45534554
if (PyBytes_Check(stream))
45544555
{
@@ -4577,8 +4578,7 @@ SWIGINTERN struct fz_document_s *new_fz_document_s(char const *filename,PyObject
45774578
doc = (fz_document *) pdf_create_document(gctx);
45784579
}
45794580
}
4580-
fz_catch(gctx)
4581-
return NULL;
4581+
fz_catch(gctx) return NULL;
45824582
return doc;
45834583
}
45844584
SWIGINTERN void fz_document_s_close(struct fz_document_s *self){
@@ -5721,7 +5721,8 @@ fz_throw(gctx, FZ_ERROR_GENERIC, "not a PDF")
57215721
fontdict = pdf_dict_get_val(gctx, dict, i);
57225722
if (!pdf_is_dict(gctx, fontdict))
57235723
continue; // not a valid font
5724-
long xref = (long) pdf_to_num(gctx, fontdict);
5724+
int xref = pdf_to_num(gctx, fontdict);
5725+
char *ext = fontextension(gctx, pdf, xref);
57255726
long gen = (long) pdf_to_gen(gctx, fontdict);
57265727
subtype = pdf_dict_get(gctx, fontdict, PDF_NAME_Subtype);
57275728
basefont = pdf_dict_get(gctx, fontdict, PDF_NAME_BaseFont);
@@ -5730,7 +5731,7 @@ fz_throw(gctx, FZ_ERROR_GENERIC, "not a PDF")
57305731
else
57315732
bname = basefont;
57325733
name = pdf_dict_get_key(gctx, dict, i);
5733-
PyList_Append(fontlist, Py_BuildValue("(i,i,s,s,s)", xref, gen,
5734+
PyList_Append(fontlist, Py_BuildValue("(i,s,s,s,s)", xref, ext,
57345735
pdf_to_name(gctx, subtype),
57355736
pdf_to_name(gctx, bname),
57365737
pdf_to_name(gctx, name)));
@@ -6451,7 +6452,7 @@ fz_throw(gctx, FZ_ERROR_GENERIC, "unknown PDF Base 14 font")
64516452
pdf_dict_puts(gctx, fonts, fontname, font_obj);
64526453
pdf_dict_put(gctx, resources, PDF_NAME_Font, fonts);
64536454
}
6454-
fz_catch(gctx) return -1;
6455+
fz_catch(gctx) return NULL;
64556456
return Py_BuildValue("(i, O)", xref, info);
64566457
}
64576458
SWIGINTERN PyObject *fz_page_s__getContents(struct fz_page_s *self){
@@ -7030,6 +7031,10 @@ fz_throw(gctx, FZ_ERROR_GENERIC, "xref out of range")
70307031
if (!pdf_name_eq(gctx, type, PDF_NAME_Image))
70317032
/*@SWIG:fitz\fitz.i,39,THROWMSG@*/
70327033
fz_throw(gctx, FZ_ERROR_GENERIC, "xref not an image")
7034+
/*@SWIG@*/;
7035+
if (!pdf_is_stream(gctx, ref))
7036+
/*@SWIG:fitz\fitz.i,39,THROWMSG@*/
7037+
fz_throw(gctx, FZ_ERROR_GENERIC, "broken PDF: xref is not a stream")
70337038
/*@SWIG@*/;
70347039
img = pdf_load_image(gctx, pdf, ref);
70357040
pdf_drop_obj(gctx, ref);
@@ -8347,7 +8352,7 @@ SWIGINTERN PyObject *_wrap_new_Document(PyObject *SWIGUNUSEDPARM(self), PyObject
83478352
}
83488353
{
83498354
result = (struct fz_document_s *)new_fz_document_s((char const *)arg1,arg2);
8350-
if(result==NULL)
8355+
if(!result)
83518356
{
83528357
PyErr_SetString(PyExc_Exception, gctx->error->message);
83538358
return NULL;
@@ -10671,7 +10676,7 @@ SWIGINTERN PyObject *_wrap_Page_insertFont(PyObject *SWIGUNUSEDPARM(self), PyObj
1067110676
}
1067210677
{
1067310678
result = (PyObject *)fz_page_s_insertFont(arg1,(char const *)arg2,(char const *)arg3,arg4,arg5);
10674-
if(result<0)
10679+
if(!result)
1067510680
{
1067610681
PyErr_SetString(PyExc_Exception, gctx->error->message);
1067710682
return NULL;

fitz/helper-other.i

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,8 @@ char *fontextension(fz_context *ctx, pdf_document *doc, int num)
630630
if (!obj)
631631
{
632632
pdf_drop_obj(ctx, o);
633-
fz_throw(ctx, FZ_ERROR_GENERIC, "invalid font - FontDescriptor missing");
633+
ext = "n/a";
634+
return ext;
634635
}
635636
pdf_drop_obj(ctx, o);
636637
o = obj;

fitz/helper-python.i

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,24 @@ def CheckMorph(o):
269269
raise ValueError("invalid morph parameter")
270270
return True
271271

272-
def CheckFont(page, font):
273-
"""Check whether a font reference is in the page's font list and return its xref.
272+
def CheckFont(page, fontname):
273+
"""Return an entry in the page's font list if reference name matches.
274274
"""
275275
fl = page.getFontList()
276-
have_ref = None
276+
refname = None
277277
for f in fl:
278-
if f[4] == font:
279-
have_ref = f
278+
if f[4] == fontname:
279+
refname = f
280280
break
281-
return have_ref
281+
return refname
282+
283+
def CheckFontInfo(doc, xref):
284+
"""Return a font info if present in the document.
285+
"""
286+
fi = None
287+
for f in doc.FontInfo:
288+
if f[0] == xref:
289+
fi = f
290+
break
291+
return fi
282292
%}

0 commit comments

Comments
 (0)