Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gsdsrc.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
17
/* DataSource procedures */
18
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gsdsrc.h"
22
#include "gserrors.h"
23
#include "stream.h"
24
25
/* GC descriptor */
26
public_st_data_source();
27
static
28
17
ENUM_PTRS_WITH(data_source_enum_ptrs, gs_data_source_t *psrc)
29
17
{
30
17
    if (psrc->type == data_source_type_string)
31
0
        ENUM_RETURN_CONST_STRING_PTR(gs_data_source_t, data.str);
32
17
    else if (psrc->type == data_source_type_stream)
33
0
        ENUM_RETURN_PTR(gs_data_source_t, data.strm);
34
17
    else      /* bytes or floats */
35
17
        ENUM_RETURN_PTR(gs_data_source_t, data.str.data);
36
17
}
37
17
ENUM_PTRS_END
38
17
static RELOC_PTRS_WITH(data_source_reloc_ptrs, gs_data_source_t *psrc)
39
17
{
40
17
    if (psrc->type == data_source_type_string)
41
17
        RELOC_CONST_STRING_PTR(gs_data_source_t, data.str);
42
17
    else if (psrc->type == data_source_type_stream)
43
17
        RELOC_PTR(gs_data_source_t, data.strm);
44
17
    else      /* bytes or floats */
45
17
        RELOC_PTR(gs_data_source_t, data.str.data);
46
17
}
47
17
RELOC_PTRS_END
48
49
/* Access data from a string or a byte object. */
50
/* Does check bounds, and returns 0 data oob. Spec calls for rangecheck,
51
   but CPSI implementation silently gives (bogus) data. */
52
int
53
data_source_access_string(const gs_data_source_t * psrc, ulong start,
54
                          uint length, byte * buf, const byte ** ptr)
55
0
{
56
0
    const byte *p = psrc->data.str.data + start;
57
58
0
    if (start + length <= psrc->data.str.size) {
59
0
        if (ptr)
60
0
            *ptr = p;
61
0
        else
62
0
            memcpy(buf, p, length);
63
0
    } else {
64
0
        if (start < psrc->data.str.size) {
65
0
            uint oklen = psrc->data.str.size - start;
66
0
            memcpy(buf, p, oklen);
67
0
            memset(buf + oklen, 0, length - oklen);
68
0
        } else {
69
0
            memset(buf, 0, length);
70
0
        }
71
0
        *ptr = buf;
72
0
    }
73
0
    return 0;
74
0
}
75
/* access_bytes is identical to access_string, but has a different */
76
/* GC procedure. */
77
int
78
data_source_access_bytes(const gs_data_source_t * psrc, ulong start,
79
                         uint length, byte * buf, const byte ** ptr)
80
7.60k
{
81
7.60k
    const byte *p = psrc->data.str.data + start;
82
83
7.60k
    if (ptr)
84
7.60k
        *ptr = p;
85
0
    else
86
0
        memcpy(buf, p, length);
87
7.60k
    return 0;
88
7.60k
}
89
90
/* Access data from a stream. */
91
/* Returns gs_error_rangecheck if out of bounds. */
92
int
93
data_source_access_stream(const gs_data_source_t * psrc, ulong start,
94
                          uint length, byte * buf, const byte ** ptr)
95
53.8M
{
96
53.8M
    stream *s = psrc->data.strm;
97
53.8M
    const byte *p;
98
99
53.8M
    if (start >= s->position &&
100
53.8M
        (p = start - s->position + s->cbuf) + length <=
101
53.8M
        s->cursor.r.limit + 1
102
53.8M
        ) {
103
53.8M
        if (ptr)
104
53.8M
            *ptr = p;
105
0
        else
106
0
            memcpy(buf, p, length);
107
53.8M
    } else {
108
0
        uint nread;
109
0
        int code = sseek(s, start);
110
111
0
        if (code < 0)
112
0
            return_error(gs_error_rangecheck);
113
0
        code = sgets(s, buf, length, &nread);
114
0
        if (code < 0)
115
0
            return_error(gs_error_rangecheck);
116
0
        if (nread != length)
117
0
            return_error(gs_error_rangecheck);
118
0
        if (ptr)
119
0
            *ptr = buf;
120
0
    }
121
53.8M
    return 0;
122
53.8M
}