Coverage Report

Created: 2025-06-10 07:24

/src/ghostpdl/base/gsfname.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
/* File name utilities */
18
#include "memory_.h"
19
#include "gserrors.h"
20
#include "gsmemory.h"
21
#include "gstypes.h"
22
#include "gsfname.h"
23
#include "gxiodev.h"
24
25
/* Parse a file name into device and individual name. */
26
/* The device may be NULL, or the name may be NULL, but not both. */
27
/* According to the Adobe documentation, %device and %device% */
28
/* are equivalent; both return name==NULL. */
29
int
30
gs_parse_file_name(gs_parsed_file_name_t * pfn, const char *pname, uint len,
31
                   const gs_memory_t *memory)
32
7.58M
{
33
7.58M
    uint dlen;
34
7.58M
    const char *pdelim;
35
7.58M
    gx_io_device *iodev;
36
37
7.58M
    if (len == 0)
38
154
        return_error(gs_error_undefinedfilename); /* null name not allowed */
39
7.58M
    if (pname[0] != '%') { /* no device */
40
3.00M
        pfn->memory = 0;
41
3.00M
        pfn->iodev = NULL;
42
3.00M
        pfn->fname = pname;
43
3.00M
        pfn->len = len;
44
3.00M
        return 0;
45
3.00M
    }
46
4.57M
    pdelim = memchr(pname + 1, '%', len - 1);
47
4.57M
    if (pdelim == NULL)    /* %device */
48
1.18M
        dlen = len;
49
    /* gs strings aren't necessarily null terminated */
50
3.38M
    else if (pdelim - pname == len - 1 || pdelim[1] == 0) { /* %device% */
51
0
        pdelim = NULL;
52
0
        dlen = len;
53
3.38M
    } else {
54
3.38M
        dlen = pdelim - pname;
55
3.38M
        pdelim++, len--;
56
3.38M
    }
57
4.57M
    iodev = gs_findiodevice(memory, (const byte *)pname, dlen);
58
4.57M
    if (iodev == 0)
59
0
        return_error(gs_error_undefinedfilename);
60
4.57M
    pfn->memory = 0;
61
4.57M
    pfn->iodev = iodev;
62
4.57M
    pfn->fname = pdelim;
63
4.57M
    pfn->len = len - dlen;
64
4.57M
    return 0;
65
4.57M
}
66
67
/* Parse a real (non-device) file name and convert to a C string. */
68
int
69
gs_parse_real_file_name(gs_parsed_file_name_t * pfn, const char *pname,
70
                        uint len, gs_memory_t *mem, client_name_t cname)
71
6.21k
{
72
6.21k
    int code = gs_parse_file_name(pfn, pname, len, mem);
73
74
6.21k
    if (code < 0)
75
0
        return code;
76
6.21k
    if (pfn->len == 0)  /* device only */
77
0
        return_error(gs_error_undefinedfilename); /* for CET 23-23.ps */
78
6.21k
    return gs_terminate_file_name(pfn, mem, cname);
79
6.21k
}
80
81
/* Convert a file name to a C string by adding a null terminator. */
82
int
83
gs_terminate_file_name(gs_parsed_file_name_t * pfn, gs_memory_t *mem,
84
                       client_name_t cname)
85
98.3k
{
86
98.3k
    uint len = pfn->len;
87
98.3k
    char *fname;
88
89
98.3k
    if (pfn->iodev == NULL)  /* no device */
90
6.21k
        pfn->iodev = iodev_default(mem);
91
98.3k
    if (pfn->memory)
92
0
        return 0;   /* already copied */
93
    /* Copy the file name to a C string. */
94
98.3k
    fname = (char *)gs_alloc_string(mem, len + 1, cname);
95
98.3k
    if (fname == 0)
96
0
        return_error(gs_error_VMerror);
97
98.3k
    memcpy(fname, pfn->fname, len);
98
98.3k
    fname[len] = 0;
99
98.3k
    pfn->memory = mem;
100
98.3k
    pfn->fname = fname;
101
98.3k
    pfn->len = len + 1;   /* null terminator */
102
98.3k
    return 0;
103
98.3k
}
104
105
/* Free a file name that was copied to a C string. */
106
void
107
gs_free_file_name(gs_parsed_file_name_t * pfn, client_name_t cname)
108
98.3k
{
109
98.3k
    if (pfn->fname != 0)
110
98.3k
        gs_free_const_string(pfn->memory, (const byte *)pfn->fname, pfn->len,
111
98.3k
                             cname);
112
98.3k
}