XpmRead.c revision 74835918
1/*
2 * Copyright (c) 2023, Oracle and/or its affiliates.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include "config.h"
25
26#include <X11/xpm.h>
27#include <glib.h>
28
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <string.h>
33
34#include "TestAllFiles.h"
35
36#ifndef g_assert_no_errno /* defined in glib 2.66 & later */
37#define g_assert_no_errno(n) g_assert_cmpint(n, >=, 0)
38#endif
39
40/*
41 * XpmReadFileToXpmImage - Read XPM files without requiring an X Display
42 *
43 * Todo: actually check the returned image/info.
44  */
45static int
46TestReadFileToXpmImage(const gchar *filepath)
47{
48    XpmImage image;
49    XpmInfo info;
50    int status;
51
52    status = XpmReadFileToXpmImage(filepath, &image, &info);
53
54    if (status == XpmSuccess) {
55        XpmFreeXpmImage(&image);
56        XpmFreeXpmInfo(&info);
57    }
58
59    return status;
60}
61
62static void
63test_XpmReadFileToXpmImage(void)
64{
65    int status;
66
67    status = TestReadFileToXpmImage("no-such-file.xpm");
68    g_assert_cmpint(status, ==, XpmOpenFailed);
69
70    TestAllNormalFiles("good", XpmSuccess, TestReadFileToXpmImage);
71    TestAllNormalFiles("invalid", XpmFileInvalid, TestReadFileToXpmImage);
72    TestAllNormalFiles("no-mem", XpmNoMemory, TestReadFileToXpmImage);
73    /* XpmReadFileToXpmImage supports compressed files */
74    TestAllCompressedFiles("good", XpmSuccess, TestReadFileToXpmImage);
75    TestAllCompressedFiles("invalid", XpmFileInvalid, TestReadFileToXpmImage);
76    TestAllCompressedFiles("no-mem", XpmNoMemory, TestReadFileToXpmImage);
77}
78
79/*
80 * XpmReadFileToData - wrapper around XpmReadFileToXpmImage that
81 * converts the image into a list of strings.
82 *
83 * Todo: actually check the returned data.
84 */
85static int
86TestReadFileToData(const gchar *filepath)
87{
88    char **data = NULL;
89    int status;
90
91    status = XpmReadFileToData(filepath, &data);
92
93    if (status == XpmSuccess) {
94        XpmImage image;
95        XpmInfo info;
96
97        g_assert_nonnull(data);
98
99        status = XpmCreateXpmImageFromData(data, &image, &info);
100        g_assert_cmpint(status, ==, XpmSuccess);
101
102        XpmFreeXpmImage(&image);
103        XpmFreeXpmInfo(&info);
104        XpmFree(data);
105    }
106
107    return status;
108}
109
110static void
111test_XpmReadFileToData(void)
112{
113    int status;
114
115    status = TestReadFileToData("no-such-file.xpm");
116    g_assert_cmpint(status, ==, XpmOpenFailed);
117
118    TestAllNormalFiles("good", XpmSuccess, TestReadFileToData);
119    TestAllNormalFiles("invalid", XpmFileInvalid, TestReadFileToData);
120    TestAllNormalFiles("no-mem", XpmNoMemory,  TestReadFileToData);
121    /* XpmReadFileToData calls XpmReadFileToXpmImage so it
122       supports compressed files */
123    TestAllCompressedFiles("good", XpmSuccess, TestReadFileToData);
124    TestAllCompressedFiles("invalid", XpmFileInvalid, TestReadFileToData);
125    TestAllCompressedFiles("no-mem", XpmNoMemory, TestReadFileToData);
126}
127
128
129/*
130 * XpmReadFileToBuffer - helper function that just reads the file
131 * into memory and doesn't try to parse it.
132 */
133static int
134TestReadFileToBuffer(const gchar *filepath)
135{
136    char *buffer = NULL;
137    int status;
138
139    status = XpmReadFileToBuffer(filepath, &buffer);
140
141    if (status == XpmSuccess) {
142        char readbuf[8192];
143        char *b = buffer;
144        int fd;
145        ssize_t rd;
146
147        g_assert_nonnull(buffer);
148
149        /* Read file ourselves and verify the data matches */
150        g_assert_no_errno(fd = open(filepath, O_RDONLY));
151        while ((rd = read(fd, readbuf, sizeof(readbuf))) > 0) {
152            g_assert_cmpmem(b, rd, readbuf, rd);
153            b += rd;
154        }
155        /* Verify a nil terminator was added to the end */
156        g_assert_cmpint(b[0], ==, '\0');
157        g_assert_no_errno(close(fd));
158
159        XpmFree(buffer);
160    }
161
162    return status;
163}
164
165static void
166test_XpmReadFileToBuffer(void)
167{
168    int status;
169
170    status = TestReadFileToBuffer("no-such-file.xpm");
171    g_assert_cmpint(status, ==, XpmOpenFailed);
172
173    TestAllNormalFiles("good", XpmSuccess, TestReadFileToBuffer);
174    /* Since this test just reads the file from disk without parsing,
175       we expect Success even from files with bad fields in. */
176    TestAllNormalFiles("invalid", XpmSuccess, TestReadFileToBuffer);
177    TestAllNormalFiles("no-mem", XpmSuccess, TestReadFileToBuffer);
178    /* XpmReadFileToBuffer does not support compressed files */
179}
180
181int
182main(int argc, char** argv)
183{
184    g_test_init(&argc, &argv, NULL);
185    g_test_bug_base(PACKAGE_BUGREPORT);
186
187    g_test_add_func("/XpmRead/XpmReadFileToXpmImage",
188                    test_XpmReadFileToXpmImage);
189    g_test_add_func("/XpmRead/XpmReadFileToData",
190                    test_XpmReadFileToData);
191    g_test_add_func("/XpmRead/XpmReadFileToBuffer",
192                    test_XpmReadFileToBuffer);
193
194    return g_test_run();
195}
196