summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-02-03 15:57:00 +0000
committerRobin Watts <robin.watts@artifex.com>2016-02-03 16:34:30 +0000
commit560db0c72d5bf6404378a8ac3bd1de9af3efa835 (patch)
tree3d1bbce6c2896651220f5358ce4eb35b10f25e2e
parent36e57486f01fc026fd1e8886b32f91e385befedc (diff)
downloadmupdf-560db0c72d5bf6404378a8ac3bd1de9af3efa835.tar.xz
Move pdf's lex_number routine over to use fast atof.
Spot (broken) values that will require special 'acrobat compatible' handling and use the old code for that.
-rw-r--r--source/pdf/pdf-lex.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/source/pdf/pdf-lex.c b/source/pdf/pdf-lex.c
index 99bf3ffd..c7ba122b 100644
--- a/source/pdf/pdf-lex.c
+++ b/source/pdf/pdf-lex.c
@@ -63,8 +63,8 @@ lex_comment(fz_context *ctx, fz_stream *f)
} while ((c != '\012') && (c != '\015') && (c != EOF));
}
-/* Fast but inaccurate strtof, with Adobe overflow handling. */
-static float fast_atof(char *s)
+/* Fast(ish) but inaccurate strtof, with Adobe overflow handling. */
+static float acrobat_compatible_atof(char *s)
{
int neg = 0;
int i = 0;
@@ -141,7 +141,8 @@ lex_number(fz_context *ctx, fz_stream *f, pdf_lexbuf *buf, int c)
{
char *s = buf->scratch;
char *e = buf->scratch + buf->size - 1; /* leave space for zero terminator */
- int isreal = (c == '.');
+ char *isreal = (c == '.' ? s : NULL);
+ int neg = (c == '-');
*s++ = c;
@@ -156,8 +157,12 @@ lex_number(fz_context *ctx, fz_stream *f, pdf_lexbuf *buf, int c)
goto end;
case EOF:
goto end;
+ case '-':
+ neg++;
+ *s++ = c;
+ break;
case '.':
- isreal = 1;
+ isreal = s;
/* Fall through */
default:
*s++ = c;
@@ -169,7 +174,15 @@ end:
*s = '\0';
if (isreal)
{
- buf->f = fast_atof(buf->scratch);
+ /* We'd like to use the fastest possible atof
+ * routine, but we'd rather match acrobats
+ * handling of broken numbers. As such, we
+ * spot common broken cases and call an
+ * acrobat compatible routine where required. */
+ if (neg > 1 || isreal - buf->scratch >= 10)
+ buf->f = acrobat_compatible_atof(buf->scratch);
+ else
+ buf->f = fz_atof(buf->scratch);
return PDF_TOK_REAL;
}
else