From d60b93b305832316c8e88694e2119935edde0178 Mon Sep 17 00:00:00 2001
From: intrigeri <intrigeri@debian.org>
Date: Tue, 22 Jan 2013 15:56:36 +0100
Subject: [PATCH 1/2] Fix Evince crash when printing certain PDF files
 (Closes: #682673)

Cherry-picked from upstream:

  5dd0f2e cff subsetting: widths can be floating point
  49c8e1b cff: use correct size for buffer
  77106a0 cff: convert '.' to locale specific decimal point before using sscanf
  2f1d6b2 cff-subsetting: Ignore charset for non cid fonts

FWIW, these patches have been shipped in Ubuntu since 1.12.2-1ubuntu2, along
with a Valgrind warning fix that I did not feel was worth a freeze exception.
---
 ...bsetting-Ignore-charset-for-non-cid-fonts.patch |   37 ++++++++++
 ..._._to_locale_specific_decimal_point_befor.patch |   68 +++++++++++++++++
 .../09_cff_use_correct_size_for_buffer.patch       |   22 ++++++
 ...f_subsetting_widths_can_be_floating_point.patch |   78 ++++++++++++++++++++
 debian/patches/series                              |    4 +
 5 files changed, 209 insertions(+)
 create mode 100644 debian/patches/07_cff-subsetting-Ignore-charset-for-non-cid-fonts.patch
 create mode 100644 debian/patches/08_cff_convert_._to_locale_specific_decimal_point_befor.patch
 create mode 100644 debian/patches/09_cff_use_correct_size_for_buffer.patch
 create mode 100644 debian/patches/10_cff_subsetting_widths_can_be_floating_point.patch

diff --git a/debian/patches/07_cff-subsetting-Ignore-charset-for-non-cid-fonts.patch b/debian/patches/07_cff-subsetting-Ignore-charset-for-non-cid-fonts.patch
new file mode 100644
index 0000000..f64cdba
--- /dev/null
+++ b/debian/patches/07_cff-subsetting-Ignore-charset-for-non-cid-fonts.patch
@@ -0,0 +1,37 @@
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Thu, 7 Jun 2012 19:18:52 +0930
+Subject: cff-subsetting: Ignore charset for non cid fonts
+
+Fixes crash in https://bugzilla.gnome.org/show_bug.cgi?id=677422
+---
+ src/cairo-cff-subset.c |   16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
+index db6fdf7..6f0cd66 100644
+--- a/src/cairo-cff-subset.c
++++ b/src/cairo-cff-subset.c
+@@ -1178,14 +1178,16 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
+         goto fail;
+     font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
+ 
+-    operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
+-    if (font->is_cid && !operand)
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
++    if (font->is_cid) {
++	 operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
++	 if (!operand)
++	      return CAIRO_INT_STATUS_UNSUPPORTED;
+ 
+-    decode_integer (operand, &offset);
+-    font->charset = font->data + offset;
+-    if (font->charset >= font->data_end)
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
++	 decode_integer (operand, &offset);
++	 font->charset = font->data + offset;
++	 if (font->charset >= font->data_end)
++	      return CAIRO_INT_STATUS_UNSUPPORTED;
++    }
+ 
+     if (!font->is_opentype)
+         cairo_cff_font_read_font_metrics (font, font->top_dict);
diff --git a/debian/patches/08_cff_convert_._to_locale_specific_decimal_point_befor.patch b/debian/patches/08_cff_convert_._to_locale_specific_decimal_point_befor.patch
new file mode 100644
index 0000000..be88949
--- /dev/null
+++ b/debian/patches/08_cff_convert_._to_locale_specific_decimal_point_befor.patch
@@ -0,0 +1,68 @@
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Wed, 4 Jul 2012 19:54:18 +0930
+Subject: cff: convert '.' to locale specific decimal point before using
+ sscanf
+
+to fix bug when decoding cff real numbers.
+
+Bug 51443
+---
+ src/cairo-cff-subset.c |   26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
+index 6f0cd66..aeaf5b1 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;
diff --git a/debian/patches/09_cff_use_correct_size_for_buffer.patch b/debian/patches/09_cff_use_correct_size_for_buffer.patch
new file mode 100644
index 0000000..d5b0f1f
--- /dev/null
+++ b/debian/patches/09_cff_use_correct_size_for_buffer.patch
@@ -0,0 +1,22 @@
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Thu, 5 Jul 2012 21:59:33 +0930
+Subject: cff: use correct size for buffer
+
+Bug 51443
+---
+ src/cairo-cff-subset.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
+index aeaf5b1..b3b6026 100644
+--- a/src/cairo-cff-subset.c
++++ b/src/cairo-cff-subset.c
+@@ -302,7 +302,7 @@ decode_real (unsigned char *p, double *real)
+     char buffer2[200];
+     char *q;
+     char *buf = buffer;
+-    char *buf_end = buffer + sizeof (buf);
++    char *buf_end = buffer + sizeof (buffer);
+ 
+     locale_data = localeconv ();
+     decimal_point = locale_data->decimal_point;
diff --git a/debian/patches/10_cff_subsetting_widths_can_be_floating_point.patch b/debian/patches/10_cff_subsetting_widths_can_be_floating_point.patch
new file mode 100644
index 0000000..b8bd051
--- /dev/null
+++ b/debian/patches/10_cff_subsetting_widths_can_be_floating_point.patch
@@ -0,0 +1,78 @@
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Tue, 31 Jul 2012 22:52:09 +0930
+Subject: cff subsetting: widths can be floating point
+
+Bug 52972
+---
+ src/cairo-cff-subset.c |   22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
+index b3b6026..21c1a0b 100644
+--- a/src/cairo-cff-subset.c
++++ b/src/cairo-cff-subset.c
+@@ -1,3 +1,4 @@
++/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+ /* cairo - a vector graphics library with display and print output
+  *
+  * Copyright © 2006 Adrian Johnson
+@@ -152,8 +153,8 @@ typedef struct _cairo_cff_font {
+     int  		 units_per_em;
+     int 		 global_sub_bias;
+     int			 local_sub_bias;
+-    int                  default_width;
+-    int                  nominal_width;
++    double               default_width;
++    double               nominal_width;
+ 
+     /* CID Font Data */
+     int                 *fdselect;
+@@ -162,8 +163,8 @@ typedef struct _cairo_cff_font {
+     cairo_hash_table_t **fd_private_dict;
+     cairo_array_t       *fd_local_sub_index;
+     int			*fd_local_sub_bias;
+-    int                 *fd_default_width;
+-    int                 *fd_nominal_width;
++    double              *fd_default_width;
++    double              *fd_nominal_width;
+ 
+     /* Subsetted Font Data */
+     char                *subset_font_name;
+@@ -910,8 +911,8 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t   *font,
+                                   cairo_array_t      *local_sub_index,
+                                   int                *local_sub_bias,
+                                   cairo_bool_t      **local_subs_used,
+-                                  int                *default_width,
+-                                  int                *nominal_width,
++                                  double             *default_width,
++                                  double             *nominal_width,
+                                   unsigned char      *ptr,
+                                   int                 size)
+ {
+@@ -946,12 +947,12 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t   *font,
+     *default_width = 0;
+     operand = cff_dict_get_operands (private_dict, DEFAULTWIDTH_OP, &i);
+     if (operand)
+-        decode_integer (operand, default_width);
++        decode_number (operand, default_width);
+ 
+     *nominal_width = 0;
+     operand = cff_dict_get_operands (private_dict, NOMINALWIDTH_OP, &i);
+     if (operand)
+-        decode_integer (operand, nominal_width);
++	 decode_number (operand, nominal_width);
+ 
+     num_subs = _cairo_array_num_elements (local_sub_index);
+     *local_subs_used = calloc (num_subs, sizeof (cairo_bool_t));
+@@ -1468,9 +1469,8 @@ type2_decode_integer (unsigned char *p, int *integer)
+         *integer = -(p[0] - 251) * 256 - p[1] - 108;
+         p += 2;
+     } else { /* *p == 255 */
+-    /* This actually a 16.16 fixed-point number however we are not interested in
+-     * the value of fixed-point numbers. */
+-        *integer = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
++	 /* 16.16 fixed-point number. The fraction is ignored. */
++	 *integer = (int16_t)((p[1] << 8) | p[2]);
+         p += 5;
+     }
+     return p;
diff --git a/debian/patches/series b/debian/patches/series
index 4575527..e262ef1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,7 @@
 03_export-symbols.patch
 05-flto.patch
 06_hurd-map-noreserve.patch
+07_cff-subsetting-Ignore-charset-for-non-cid-fonts.patch
+08_cff_convert_._to_locale_specific_decimal_point_befor.patch
+09_cff_use_correct_size_for_buffer.patch
+10_cff_subsetting_widths_can_be_floating_point.patch
-- 
1.7.10.4

