Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_stack.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Stack operations for the PDF interpreter */
17
18
#include "ghostpdf.h"
19
#include "pdf_types.h"
20
#include "pdf_int.h"
21
#include "pdf_stack.h"
22
23
int pdfi_pop(pdf_context *ctx, int num)
24
579M
{
25
579M
    int code = 0;
26
579M
    if (num < 0)
27
123k
        return_error(gs_error_rangecheck);
28
29
579M
    if (pdfi_count_stack(ctx) < num) {
30
37.1k
        code = gs_note_error(gs_error_stackunderflow);
31
37.1k
        num = pdfi_count_stack(ctx);
32
37.1k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_STACKUNDERFLOW, "pdfi_pop", NULL);
33
37.1k
    }
34
1.52G
    while(num) {
35
944M
        pdfi_countdown(ctx->stack_top[-1]);
36
944M
        ctx->stack_top--;
37
944M
        num--;
38
944M
    }
39
579M
    return code;
40
579M
}
41
42
int pdfi_push(pdf_context *ctx, pdf_obj *o)
43
944M
{
44
944M
    pdf_obj **new_stack;
45
944M
    uint32_t entries = 0;
46
47
944M
    if (ctx->stack_top < ctx->stack_bot)
48
113k
        ctx->stack_top = ctx->stack_bot;
49
50
944M
    if (ctx->stack_top >= ctx->stack_limit) {
51
688k
        if (ctx->stack_size >= MAX_STACK_SIZE)
52
1.07k
            return_error(gs_error_pdf_stackoverflow);
53
54
687k
        new_stack = (pdf_obj **)gs_alloc_bytes(ctx->memory, (size_t)(ctx->stack_size + INITIAL_STACK_SIZE) * sizeof (pdf_obj *), "pdfi_push_increase_interp_stack");
55
687k
        if (new_stack == NULL)
56
0
            return_error(gs_error_VMerror);
57
58
687k
        memcpy(new_stack, ctx->stack_bot, ctx->stack_size * sizeof(pdf_obj *));
59
687k
        gs_free_object(ctx->memory, ctx->stack_bot, "pdfi_push_increase_interp_stack");
60
61
687k
        entries = pdfi_count_total_stack(ctx);
62
63
687k
        ctx->stack_bot = new_stack;
64
687k
        ctx->stack_top = ctx->stack_bot + entries;
65
687k
        ctx->stack_size += INITIAL_STACK_SIZE;
66
687k
        ctx->stack_limit = ctx->stack_bot + ctx->stack_size;
67
687k
    }
68
69
944M
    *ctx->stack_top = o;
70
944M
    ctx->stack_top++;
71
944M
    pdfi_countup(o);
72
73
944M
    return 0;
74
944M
}
75
76
int pdfi_mark_stack(pdf_context *ctx, pdf_obj_type type)
77
39.1M
{
78
39.1M
    pdf_obj *o;
79
39.1M
    int code;
80
81
39.1M
    if (type != PDF_ARRAY_MARK && type != PDF_DICT_MARK && type != PDF_PROC_MARK)
82
0
        return_error(gs_error_typecheck);
83
84
39.1M
    code = pdfi_object_alloc(ctx, type, 0, &o);
85
39.1M
    if (code < 0)
86
0
        return code;
87
88
39.1M
    code = pdfi_push(ctx, o);
89
39.1M
    if (code < 0)
90
1
        pdfi_free_object(o);
91
39.1M
    return code;
92
39.1M
}
93
94
void pdfi_clearstack(pdf_context *ctx)
95
40.9M
{
96
40.9M
    pdfi_pop(ctx, pdfi_count_stack(ctx));
97
40.9M
}
98
99
int pdfi_count_to_mark(pdf_context *ctx, uint64_t *count)
100
75.6M
{
101
75.6M
    pdf_obj *o = ctx->stack_top[- 1];
102
75.6M
    int index = -1;
103
75.6M
    pdf_obj **save_bot = NULL;
104
105
75.6M
    save_bot = ctx->stack_bot + ctx->current_stream_save.stack_count;
106
107
75.6M
    *count = 0;
108
426M
    while (&ctx->stack_top[index] >= save_bot) {
109
426M
        if (pdfi_type_of(o) == PDF_ARRAY_MARK || pdfi_type_of(o) == PDF_DICT_MARK || pdfi_type_of(o) == PDF_PROC_MARK )
110
74.8M
            return 0;
111
351M
        o = ctx->stack_top[--index];
112
351M
        (*count)++;
113
351M
    }
114
75.6M
    return_error(gs_error_unmatchedmark);
115
75.6M
}
116
117
int pdfi_clear_to_mark(pdf_context *ctx)
118
37.8M
{
119
37.8M
    int code;
120
37.8M
    uint64_t count;
121
122
37.8M
    code = pdfi_count_to_mark(ctx, &count);
123
37.8M
    if (code < 0)
124
322k
        return code;
125
37.5M
    return pdfi_pop(ctx, count + 1);
126
37.8M
}
127
128
int
129
pdfi_destack_real(pdf_context *ctx, double *d)
130
9.06M
{
131
9.06M
    int code;
132
133
9.06M
    if (pdfi_count_stack(ctx) < 1)
134
63.1k
        return_error(gs_error_stackunderflow);
135
136
9.00M
    code = pdfi_obj_to_real(ctx, ctx->stack_top[-1], d);
137
9.00M
    if (code < 0) {
138
64.8k
        pdfi_clearstack(ctx);
139
64.8k
        return code;
140
64.8k
    }
141
8.93M
    pdfi_pop(ctx, 1);
142
143
8.93M
    return 0;
144
9.00M
}
145
146
int
147
pdfi_destack_reals(pdf_context *ctx, double *d, int n)
148
59.7M
{
149
59.7M
    int i, code;
150
151
59.7M
    if (pdfi_count_stack(ctx) < n) {
152
2.99M
        pdfi_clearstack(ctx);
153
2.99M
        return_error(gs_error_stackunderflow);
154
2.99M
    }
155
156
256M
    for (i = 0; i < n; i++) {
157
199M
        code = pdfi_obj_to_real(ctx, ctx->stack_top[i-n], &d[i]);
158
199M
        if (code < 0) {
159
307k
            pdfi_clearstack(ctx);
160
307k
            return code;
161
307k
        }
162
199M
    }
163
56.4M
    pdfi_pop(ctx, n);
164
165
56.4M
    return 0;
166
56.7M
}
167
168
int
169
pdfi_destack_floats(pdf_context *ctx, float *d, int n)
170
3.08M
{
171
3.08M
    int i, code;
172
173
3.08M
    if (pdfi_count_stack(ctx) < n) {
174
259k
        pdfi_clearstack(ctx);
175
259k
        return_error(gs_error_stackunderflow);
176
259k
    }
177
178
19.7M
    for (i = 0; i < n; i++) {
179
16.8M
        code = pdfi_obj_to_float(ctx, ctx->stack_top[i-n], &d[i]);
180
16.8M
        if (code < 0) {
181
8.00k
            pdfi_clearstack(ctx);
182
8.00k
            return code;
183
8.00k
        }
184
16.8M
    }
185
2.81M
    pdfi_pop(ctx, n);
186
187
2.81M
    return 0;
188
2.82M
}
189
190
int
191
pdfi_destack_int(pdf_context *ctx, int64_t *i)
192
3.82M
{
193
3.82M
    int code;
194
195
3.82M
    if (pdfi_count_stack(ctx) < 1)
196
4.79k
        return_error(gs_error_stackunderflow);
197
198
3.82M
    code = pdfi_obj_to_int(ctx, ctx->stack_top[-1], i);
199
3.82M
    if (code < 0) {
200
52.0k
        pdfi_clearstack(ctx);
201
52.0k
        return code;
202
52.0k
    }
203
3.77M
    pdfi_pop(ctx, 1);
204
205
3.77M
    return 0;
206
3.82M
}
207
208
int
209
pdfi_destack_ints(pdf_context *ctx, int64_t *i64, int n)
210
0
{
211
0
    int i, code;
212
213
0
    if (pdfi_count_stack(ctx) < n) {
214
0
        pdfi_clearstack(ctx);
215
0
        return_error(gs_error_stackunderflow);
216
0
    }
217
218
0
    for (i = 0; i < n; i++) {
219
0
        code = pdfi_obj_to_int(ctx, ctx->stack_top[i-n], &i64[i]);
220
0
        if (code < 0) {
221
0
            pdfi_clearstack(ctx);
222
0
            return code;
223
0
        }
224
0
    }
225
0
    pdfi_pop(ctx, n);
226
227
0
    return 0;
228
0
}