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