$OpenBSD: patch-source_xps_xps-common_c,v 1.1 2014/02/15 22:42:07 sthen Exp $

From 60dabde18d7fe12b19da8b509bdfee9cc886aafc Mon Sep 17 00:00:00 2001
From: =?utf8?q?Simon=20B=C3=BCnzli?= <zeniko@gmail.com>
Date: Thu, 16 Jan 2014 22:04:51 +0100
Subject: [PATCH] Bug 694957: fix stack buffer overflow in xps_parse_color

--- source/xps/xps-common.c.orig	Wed Aug 14 13:41:20 2013
+++ source/xps/xps-common.c	Sat Feb 15 18:39:51 2014
@@ -89,7 +89,7 @@ xps_begin_opacity(xps_document *doc, const fz_matrix *
 		if (scb_color_att)
 		{
 			fz_colorspace *colorspace;
-			float samples[32];
+			float samples[FZ_MAX_COLORS];
 			xps_parse_color(doc, base_uri, scb_color_att, &colorspace, samples);
 			opacity = opacity * samples[0];
 		}
@@ -208,12 +208,13 @@ void
 xps_parse_color(xps_document *doc, char *base_uri, char *string,
 		fz_colorspace **csp, float *samples)
 {
+	fz_context *ctx = doc->ctx;
 	char *p;
 	int i, n;
 	char buf[1024];
 	char *profile;
 
-	*csp = fz_device_rgb(doc->ctx);
+	*csp = fz_device_rgb(ctx);
 
 	samples[0] = 1;
 	samples[1] = 0;
@@ -259,7 +260,7 @@ xps_parse_color(xps_document *doc, char *base_uri, cha
 		profile = strchr(buf, ' ');
 		if (!profile)
 		{
-			fz_warn(doc->ctx, "cannot find icc profile uri in '%s'", string);
+			fz_warn(ctx, "cannot find icc profile uri in '%s'", string);
 			return;
 		}
 
@@ -267,12 +268,17 @@ xps_parse_color(xps_document *doc, char *base_uri, cha
 		p = strchr(profile, ' ');
 		if (!p)
 		{
-			fz_warn(doc->ctx, "cannot find component values in '%s'", profile);
+			fz_warn(ctx, "cannot find component values in '%s'", profile);
 			return;
 		}
 
 		*p++ = 0;
 		n = count_commas(p) + 1;
+		if (n > FZ_MAX_COLORS)
+		{
+			fz_warn(ctx, "ignoring %d color components (max %d allowed)", n - FZ_MAX_COLORS, FZ_MAX_COLORS);
+			n = FZ_MAX_COLORS;
+		}
 		i = 0;
 		while (i < n)
 		{
@@ -292,10 +298,10 @@ xps_parse_color(xps_document *doc, char *base_uri, cha
 		/* TODO: load ICC profile */
 		switch (n)
 		{
-		case 2: *csp = fz_device_gray(doc->ctx); break;
-		case 4: *csp = fz_device_rgb(doc->ctx); break;
-		case 5: *csp = fz_device_cmyk(doc->ctx); break;
-		default: *csp = fz_device_gray(doc->ctx); break;
+		case 2: *csp = fz_device_gray(ctx); break;
+		case 4: *csp = fz_device_rgb(ctx); break;
+		case 5: *csp = fz_device_cmyk(ctx); break;
+		default: *csp = fz_device_gray(ctx); break;
 		}
 	}
 }
