Greenbone Vulnerability Management Libraries 23.9.3
compressutils.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013-2023 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
10
14#if !defined(ZLIB_CONST)
15#define ZLIB_CONST
16#endif
17
18#define _GNU_SOURCE
19
20#include "compressutils.h"
21
22#include <glib.h> /* for g_free, g_malloc0 */
23#include <zlib.h> /* for z_stream, Z_NULL, Z_OK, Z_BUF_ERROR, Z_STREAM_END */
24
25#undef G_LOG_DOMAIN
29#define G_LOG_DOMAIN "libgvm util"
30
41void *
42gvm_compress (const void *src, unsigned long srclen, unsigned long *dstlen)
43{
44 unsigned long buflen = srclen * 2;
45
46 if (src == NULL || dstlen == NULL)
47 return NULL;
48
49 if (buflen < 30)
50 buflen = 30;
51
52 while (1)
53 {
54 int err;
55 void *buffer;
56 z_stream strm;
57
58 /* Initialize deflate state */
59 strm.zalloc = Z_NULL;
60 strm.zfree = Z_NULL;
61 strm.opaque = Z_NULL;
62 strm.avail_in = srclen;
63#ifdef z_const
64 strm.next_in = src;
65#else
66 /* Workaround for older zlib. */
67 strm.next_in = (void *) src;
68#endif
69 if (deflateInit (&strm, Z_DEFAULT_COMPRESSION) != Z_OK)
70 return NULL;
71
72 buffer = g_malloc0 (buflen);
73 strm.avail_out = buflen;
74 strm.next_out = buffer;
75
76 err = deflate (&strm, Z_SYNC_FLUSH);
77 deflateEnd (&strm);
78 switch (err)
79 {
80 case Z_OK:
81 case Z_STREAM_END:
82 if (strm.avail_out != 0)
83 {
84 *dstlen = strm.total_out;
85 return buffer;
86 }
87 /* Fallthrough. */
88 case Z_BUF_ERROR:
89 g_free (buffer);
90 buflen *= 2;
91 break;
92
93 default:
94 g_free (buffer);
95 return NULL;
96 }
97 }
98}
99
110void *
111gvm_uncompress (const void *src, unsigned long srclen, unsigned long *dstlen)
112{
113 unsigned long buflen;
114
115 if (src == NULL || dstlen == NULL || srclen == 0)
116 return NULL;
117
118 if (srclen >= SSIZE_MAX)
119 return NULL;
120
121 if (srclen > SSIZE_MAX / 2)
122 buflen = SSIZE_MAX;
123 else
124 buflen = srclen * 2;
125
126 while (1)
127 {
128 int err;
129 void *buffer;
130 z_stream strm;
131
132 /* Initialize inflate state */
133 strm.zalloc = Z_NULL;
134 strm.zfree = Z_NULL;
135 strm.opaque = Z_NULL;
136 strm.avail_in = srclen;
137#ifdef z_const
138 strm.next_in = src;
139#else
140 /* Workaround for older zlib. */
141 strm.next_in = (void *) src;
142#endif
143 /*
144 * From: http://www.zlib.net/manual.html
145 * Add 32 to windowBits to enable zlib and gzip decoding with automatic
146 * header detection.
147 */
148 if (inflateInit2 (&strm, 15 + 32) != Z_OK)
149 return NULL;
150
151 buffer = g_malloc0 (buflen);
152 strm.avail_out = buflen;
153 strm.next_out = buffer;
154
155 err = inflate (&strm, Z_SYNC_FLUSH);
156 inflateEnd (&strm);
157 switch (err)
158 {
159 case Z_OK:
160 case Z_STREAM_END:
161 if (strm.avail_out != 0)
162 {
163 *dstlen = strm.total_out;
164 return buffer;
165 }
166 /* Fallthrough. */
167 case Z_BUF_ERROR:
168 g_free (buffer);
169 if (buflen >= SSIZE_MAX)
170 return NULL;
171 else if (srclen > SSIZE_MAX / 2)
172 buflen = SSIZE_MAX;
173 else
174 buflen *= 2;
175 break;
176
177 default:
178 g_free (buffer);
179 return NULL;
180 }
181 }
182}
183
194void *
195gvm_compress_gzipheader (const void *src, unsigned long srclen,
196 unsigned long *dstlen)
197{
198 unsigned long buflen = srclen * 2;
199 int windowsBits = 15;
200 int GZIP_ENCODING = 16;
201
202 if (src == NULL || dstlen == NULL)
203 return NULL;
204
205 if (buflen < 30)
206 buflen = 30;
207
208 while (1)
209 {
210 int err;
211 void *buffer;
212 z_stream strm;
213
214 /* Initialize deflate state */
215 strm.zalloc = Z_NULL;
216 strm.zfree = Z_NULL;
217 strm.opaque = Z_NULL;
218 strm.avail_in = srclen;
219#ifdef z_const
220 strm.next_in = src;
221#else
222 /* Workaround for older zlib. */
223 strm.next_in = (void *) src;
224#endif
225
226 if (deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
227 windowsBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY)
228 != Z_OK)
229 return NULL;
230
231 buffer = g_malloc0 (buflen);
232 strm.avail_out = buflen;
233 strm.next_out = buffer;
234
235 err = deflate (&strm, Z_FINISH);
236 deflateEnd (&strm);
237 switch (err)
238 {
239 case Z_OK:
240 case Z_STREAM_END:
241 if (strm.avail_out != 0)
242 {
243 *dstlen = strm.total_out;
244 return buffer;
245 }
246 /* Fallthrough. */
247 case Z_BUF_ERROR:
248 g_free (buffer);
249 buflen *= 2;
250 break;
251
252 default:
253 g_free (buffer);
254 return NULL;
255 }
256 }
257}
258
268static ssize_t
269gz_file_read (void *cookie, char *buffer, size_t buffer_size)
270{
271 gzFile gz_file = cookie;
272
273 return gzread (gz_file, buffer, buffer_size);
274}
275
283static int
284gz_file_close (void *cookie)
285{
286 gzFile gz_file = cookie;
287
288 return gzclose (gz_file);
289 ;
290}
291
299FILE *
301{
302 static cookie_io_functions_t io_functions = {
303 .read = gz_file_read,
304 .write = NULL,
305 .seek = NULL,
306 .close = gz_file_close,
307 };
308
309 if (path == NULL)
310 {
311 return NULL;
312 }
313
314 gzFile gz_file = gzopen (path, "r");
315 if (gz_file == NULL)
316 {
317 return NULL;
318 }
319
320 FILE *file = fopencookie (gz_file, "r", io_functions);
321 return file;
322}
323
331FILE *
333{
334 static cookie_io_functions_t io_functions = {
335 .read = gz_file_read,
336 .write = NULL,
337 .seek = NULL,
338 .close = gz_file_close,
339 };
340
341 if (fd < 0)
342 {
343 return NULL;
344 }
345
346 gzFile gz_file = gzdopen (fd, "r");
347 if (gz_file == NULL)
348 {
349 return NULL;
350 }
351
352 FILE *file = fopencookie (gz_file, "r", io_functions);
353 return file;
354}
FILE * gvm_gzip_open_file_reader_fd(int fd)
Opens a gzip file as a FILE* stream for reading and decompression.
Definition compressutils.c:332
void * gvm_uncompress(const void *src, unsigned long srclen, unsigned long *dstlen)
Uncompresses data in src buffer.
Definition compressutils.c:111
void * gvm_compress(const void *src, unsigned long srclen, unsigned long *dstlen)
Compresses data in src buffer.
Definition compressutils.c:42
FILE * gvm_gzip_open_file_reader(const char *path)
Opens a gzip file as a FILE* stream for reading and decompression.
Definition compressutils.c:300
static int gz_file_close(void *cookie)
Close a gzip file.
Definition compressutils.c:284
static ssize_t gz_file_read(void *cookie, char *buffer, size_t buffer_size)
Read decompressed data from a gzip file.
Definition compressutils.c:269
void * gvm_compress_gzipheader(const void *src, unsigned long srclen, unsigned long *dstlen)
Compresses data in src buffer, gzip format compatible.
Definition compressutils.c:195
API related to data compression (gzip format.).