summaryrefslogtreecommitdiff
path: root/xps
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2023-01-09 16:11:05 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2023-01-10 08:57:39 -0800
commitd0850f5dffb68f433104a6bc8cc5eec3648450e0 (patch)
tree18b0c4a69d6ca1a5ae76fd9e88767eefa0f1b25d /xps
parentde989373224e6364a37270a7721ef9965b54e88c (diff)
downloadghostpdl-d0850f5dffb68f433104a6bc8cc5eec3648450e0.tar.gz
Bug 706120 XPS dash buffer overrun
Avoid overrun of fixed sized array by doing dynamic allocation and reallocating when needed.
Diffstat (limited to 'xps')
-rw-r--r--xps/xpspath.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/xps/xpspath.c b/xps/xpspath.c
index 8bb7f97fa..79e33e22d 100644
--- a/xps/xpspath.c
+++ b/xps/xpspath.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2023 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -17,6 +17,9 @@
#include "ghostxps.h"
+#define INITIAL_DASH_SIZE 32
+#define ADDITIVE_DASH_SIZE 1024
+
char *
xps_get_real_params(char *s, int num, float *x)
{
@@ -993,9 +996,21 @@ xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_ite
if (stroke_dash_array_att)
{
char *s = stroke_dash_array_att;
- float dash_array[100];
+ float *dash_array;
float dash_offset = 0.0;
int dash_count = 0;
+ int dash_mem_count = 0;
+
+ /* Do an initial reasonable allocation. If that
+ runs out, double until we get to a max size
+ and then just add that max each overrun. */
+ dash_array = xps_alloc(ctx, sizeof(float) * INITIAL_DASH_SIZE);
+ if (dash_array == NULL)
+ {
+ gs_throw(gs_error_VMerror, "out of memory: dash_array.\n");
+ return gs_error_VMerror;
+ }
+ dash_mem_count = INITIAL_DASH_SIZE;
if (stroke_dash_offset_att)
dash_offset = atof(stroke_dash_offset_att) * linewidth;
@@ -1005,7 +1020,24 @@ xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_ite
while (*s == ' ')
s++;
if (*s) /* needed in case of a space before the last quote */
+ {
+ /* Double up to a max size of ADDITIVE_DASH_SIZE and then add
+ that amount each time */
+ if (dash_count > (dash_mem_count - 1))
+ {
+ if (dash_mem_count < ADDITIVE_DASH_SIZE)
+ dash_mem_count = dash_mem_count * 2;
+ else
+ dash_mem_count = dash_mem_count + ADDITIVE_DASH_SIZE;
+ dash_array = (float*) xps_realloc(ctx, dash_array, sizeof(float) * dash_mem_count);
+ if (dash_array == NULL)
+ {
+ gs_throw(gs_error_VMerror, "out of memory: dash_array realloc.\n");
+ return gs_error_VMerror;
+ }
+ }
dash_array[dash_count++] = atof(s) * linewidth;
+ }
while (*s && *s != ' ')
s++;
}
@@ -1019,8 +1051,8 @@ xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_ite
if (phase_len == 0)
dash_count = 0;
}
-
gs_setdash(ctx->pgs, dash_array, dash_count, dash_offset);
+ xps_free(ctx, dash_array);
}
else
{