summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2011-05-31 15:49:39 +0100
committerTor Andersson <tor.andersson@artifex.com>2011-05-31 17:28:21 +0200
commit97b83d84e3d10ccd298f9c54713323a3e41ce7f3 (patch)
tree4877fbe7f4d2afff109b3bafa11bed6c013afd5b
parent89bf9896bd9d05500ac6494452a1b9d9cf8a67cb (diff)
downloadmupdf-97b83d84e3d10ccd298f9c54713323a3e41ce7f3.tar.xz
Fix assert in scale: see Bug 692245.
Bug 692245 gives a file that produces a runtime assert in mupdf due to an extremely large ctm offset (unrepresentable in a float). We fix our code here so that such floats are always read as 1.0. In this particular case, the exact value read doesn't seem to matter. We match acrobat. We pick 1.0 rather than 0.0 as this is less likely to provoke division by 0 errors later on.
-rw-r--r--fitz/base_string.c18
-rw-r--r--fitz/fitz.h3
-rw-r--r--pdf/pdf_function.c2
-rw-r--r--pdf/pdf_interpret.c4
-rw-r--r--pdf/pdf_parse.c8
-rw-r--r--pdf/pdf_xref.c2
6 files changed, 29 insertions, 8 deletions
diff --git a/fitz/base_string.c b/fitz/base_string.c
index 72a7a556..76748e20 100644
--- a/fitz/base_string.c
+++ b/fitz/base_string.c
@@ -245,3 +245,21 @@ runelen(int c)
char str[10];
return runetochar(str, &c);
}
+
+float fz_atof(const char *s)
+{
+ double d;
+
+ /* The errno voodoo here checks for us reading numbers that are too
+ * big to fit into a double. The checks for FLT_MAX ensure that we
+ * don't read a number that's OK as a double and then become invalid
+ * as we convert to a float. */
+ errno = 0;
+ d = strtod(s, NULL);
+ if (errno == ERANGE || d > FLT_MAX || d < -FLT_MAX) {
+ /* Return 1.0, as it's a small known value that won't cause a
+ * divide by 0. */
+ return 1.0;
+ }
+ return (float)d;
+}
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 9ba9d0b1..28306cfc 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -151,6 +151,9 @@ char *fz_strsep(char **stringp, const char *delim);
int fz_strlcpy(char *dst, const char *src, int n);
int fz_strlcat(char *dst, const char *src, int n);
+/* Range checking atof */
+float fz_atof(const char *s);
+
/* utf-8 encoding and decoding */
int chartorune(int *rune, char *str);
int runetochar(char *str, int *rune);
diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c
index 6237bd42..c1132365 100644
--- a/pdf/pdf_function.c
+++ b/pdf/pdf_function.c
@@ -714,7 +714,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
case PDF_TOK_REAL:
resize_code(func, *codeptr);
func->u.p.code[*codeptr].type = PS_REAL;
- func->u.p.code[*codeptr].u.f = atof(buf);
+ func->u.p.code[*codeptr].u.f = fz_atof(buf);
++*codeptr;
break;
diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c
index bad35fc6..9887ee6f 100644
--- a/pdf/pdf_interpret.c
+++ b/pdf/pdf_interpret.c
@@ -2135,7 +2135,7 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
else if (tok == PDF_TOK_INT || tok == PDF_TOK_REAL)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- pdf_show_space(csi, -atof(buf) * gstate->size * 0.001f);
+ pdf_show_space(csi, -fz_atof(buf) * gstate->size * 0.001f);
}
else if (tok == PDF_TOK_STRING)
{
@@ -2189,7 +2189,7 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
break;
case PDF_TOK_REAL:
- csi->stack[csi->top] = atof(buf);
+ csi->stack[csi->top] = fz_atof(buf);
csi->top ++;
break;
diff --git a/pdf/pdf_parse.c b/pdf/pdf_parse.c
index 31a2bd0c..d6497bc4 100644
--- a/pdf/pdf_parse.c
+++ b/pdf/pdf_parse.c
@@ -251,7 +251,7 @@ pdf_parse_array(fz_obj **op, pdf_xref *xref, fz_stream *file, char *buf, int cap
fz_drop_obj(obj);
break;
case PDF_TOK_REAL:
- obj = fz_new_real(atof(buf));
+ obj = fz_new_real(fz_atof(buf));
fz_array_push(ary, obj);
fz_drop_obj(obj);
break;
@@ -358,7 +358,7 @@ skip:
break;
case PDF_TOK_NAME: val = fz_new_name(buf); break;
- case PDF_TOK_REAL: val = fz_new_real(atof(buf)); break;
+ case PDF_TOK_REAL: val = fz_new_real(fz_atof(buf)); break;
case PDF_TOK_STRING: val = fz_new_string(buf, len); break;
case PDF_TOK_TRUE: val = fz_new_bool(1); break;
case PDF_TOK_FALSE: val = fz_new_bool(0); break;
@@ -439,7 +439,7 @@ pdf_parse_stm_obj(fz_obj **op, pdf_xref *xref, fz_stream *file, char *buf, int c
return fz_rethrow(error, "cannot parse object stream");
break;
case PDF_TOK_NAME: *op = fz_new_name(buf); break;
- case PDF_TOK_REAL: *op = fz_new_real(atof(buf)); break;
+ case PDF_TOK_REAL: *op = fz_new_real(fz_atof(buf)); break;
case PDF_TOK_STRING: *op = fz_new_string(buf, len); break;
case PDF_TOK_TRUE: *op = fz_new_bool(1); break;
case PDF_TOK_FALSE: *op = fz_new_bool(0); break;
@@ -502,7 +502,7 @@ pdf_parse_ind_obj(fz_obj **op, pdf_xref *xref,
break;
case PDF_TOK_NAME: obj = fz_new_name(buf); break;
- case PDF_TOK_REAL: obj = fz_new_real(atof(buf)); break;
+ case PDF_TOK_REAL: obj = fz_new_real(fz_atof(buf)); break;
case PDF_TOK_STRING: obj = fz_new_string(buf, len); break;
case PDF_TOK_TRUE: obj = fz_new_bool(1); break;
case PDF_TOK_FALSE: obj = fz_new_bool(0); break;
diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c
index 60b0f2d6..0e29625c 100644
--- a/pdf/pdf_xref.c
+++ b/pdf/pdf_xref.c
@@ -22,7 +22,7 @@ pdf_load_version(pdf_xref *xref)
if (memcmp(buf, "%PDF-", 5) != 0)
return fz_throw("cannot recognize version marker");
- xref->version = atof(buf + 5) * 10;
+ xref->version = fz_atof(buf + 5) * 10;
return fz_okay;
}