diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2012-07-04 19:54:18 +0930 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2012-07-04 19:54:18 +0930 |
commit | 77106a038bcd0dd503d383729f14134f76a664b2 (patch) | |
tree | c0a4c529f3058225159d4f0bdb423018f21e104f /src/cairo-cff-subset.c | |
parent | 64d65f72e5dbc1d9fa2cb4738d93eadc7fd5d7c0 (diff) |
cff: convert '.' to locale specific decimal point before using sscanf
to fix bug when decoding cff real numbers.
Bug 51443
Diffstat (limited to 'src/cairo-cff-subset.c')
-rw-r--r-- | src/cairo-cff-subset.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c index 6f0cd66f3..aeaf5b114 100644 --- a/src/cairo-cff-subset.c +++ b/src/cairo-cff-subset.c @@ -51,6 +51,7 @@ #include "cairo-scaled-font-subsets-private.h" #include "cairo-truetype-subset-private.h" #include <string.h> +#include <locale.h> /* CFF Dict Operators. If the high byte is 0 the command is encoded * with a single byte. */ @@ -293,11 +294,23 @@ decode_nibble (int n, char *buf) static unsigned char * decode_real (unsigned char *p, double *real) { + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; int n; char buffer[100]; + char buffer2[200]; + char *q; char *buf = buffer; char *buf_end = buffer + sizeof (buf); + locale_data = localeconv (); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen (decimal_point); + + assert (decimal_point_len != 0); + assert (sizeof(buffer) + decimal_point_len < sizeof(buffer2)); + p++; while (buf + 2 < buf_end) { n = *p >> 4; @@ -312,7 +325,18 @@ decode_real (unsigned char *p, double *real) }; *buf = 0; - if (sscanf(buffer, "%lf", real) != 1) + buf = buffer; + if (strchr (buffer, '.')) { + q = strchr (buffer, '.'); + strncpy (buffer2, buffer, q - buffer); + buf = buffer2 + (q - buffer); + strncpy (buf, decimal_point, decimal_point_len); + buf += decimal_point_len; + strcpy (buf, q + 1); + buf = buffer2; + } + + if (sscanf(buf, "%lf", real) != 1) *real = 0.0; return p; |