Greenbone Vulnerability Management Libraries 22.30.0
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 = srclen * 2;
114
115 if (src == NULL || dstlen == NULL)
116 return NULL;
117
118 while (1)
119 {
120 int err;
121 void *buffer;
122 z_stream strm;
123
124 /* Initialize inflate state */
125 strm.zalloc = Z_NULL;
126 strm.zfree = Z_NULL;
127 strm.opaque = Z_NULL;
128 strm.avail_in = srclen;
129#ifdef z_const
130 strm.next_in = src;
131#else
132 /* Workaround for older zlib. */
133 strm.next_in = (void *) src;
134#endif
135 /*
136 * From: http://www.zlib.net/manual.html
137 * Add 32 to windowBits to enable zlib and gzip decoding with automatic
138 * header detection.
139 */
140 if (inflateInit2 (&strm, 15 + 32) != Z_OK)
141 return NULL;
142
143 buffer = g_malloc0 (buflen);
144 strm.avail_out = buflen;
145 strm.next_out = buffer;
146
147 err = inflate (&strm, Z_SYNC_FLUSH);
148 inflateEnd (&strm);
149 switch (err)
150 {
151 case Z_OK:
152 case Z_STREAM_END:
153 if (strm.avail_out != 0)
154 {
155 *dstlen = strm.total_out;
156 return buffer;
157 }
158 /* Fallthrough. */
159 case Z_BUF_ERROR:
160 g_free (buffer);
161 buflen *= 2;
162 break;
163
164 default:
165 g_free (buffer);
166 return NULL;
167 }
168 }
169}
170
181void *
182gvm_compress_gzipheader (const void *src, unsigned long srclen,
183 unsigned long *dstlen)
184{
185 unsigned long buflen = srclen * 2;
186 int windowsBits = 15;
187 int GZIP_ENCODING = 16;
188
189 if (src == NULL || dstlen == NULL)
190 return NULL;
191
192 if (buflen < 30)
193 buflen = 30;
194
195 while (1)
196 {
197 int err;
198 void *buffer;
199 z_stream strm;
200
201 /* Initialize deflate state */
202 strm.zalloc = Z_NULL;
203 strm.zfree = Z_NULL;
204 strm.opaque = Z_NULL;
205 strm.avail_in = srclen;
206#ifdef z_const
207 strm.next_in = src;
208#else
209 /* Workaround for older zlib. */
210 strm.next_in = (void *) src;
211#endif
212
213 if (deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
214 windowsBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY)
215 != Z_OK)
216 return NULL;
217
218 buffer = g_malloc0 (buflen);
219 strm.avail_out = buflen;
220 strm.next_out = buffer;
221
222 err = deflate (&strm, Z_FINISH);
223 deflateEnd (&strm);
224 switch (err)
225 {
226 case Z_OK:
227 case Z_STREAM_END:
228 if (strm.avail_out != 0)
229 {
230 *dstlen = strm.total_out;
231 return buffer;
232 }
233 /* Fallthrough. */
234 case Z_BUF_ERROR:
235 g_free (buffer);
236 buflen *= 2;
237 break;
238
239 default:
240 g_free (buffer);
241 return NULL;
242 }
243 }
244}
245
255static ssize_t
256gz_file_read (void *cookie, char *buffer, size_t buffer_size)
257{
258 gzFile gz_file = cookie;
259
260 return gzread (gz_file, buffer, buffer_size);
261}
262
270static int
271gz_file_close (void *cookie)
272{
273 gzFile gz_file = cookie;
274
275 return gzclose (gz_file);
276 ;
277}
278
286FILE *
288{
289 static cookie_io_functions_t io_functions = {
290 .read = gz_file_read,
291 .write = NULL,
292 .seek = NULL,
293 .close = gz_file_close,
294 };
295
296 if (path == NULL)
297 {
298 return NULL;
299 }
300
301 gzFile gz_file = gzopen (path, "r");
302 if (gz_file == NULL)
303 {
304 return NULL;
305 }
306
307 FILE *file = fopencookie (gz_file, "r", io_functions);
308 return file;
309}
310
318FILE *
320{
321 static cookie_io_functions_t io_functions = {
322 .read = gz_file_read,
323 .write = NULL,
324 .seek = NULL,
325 .close = gz_file_close,
326 };
327
328 if (fd < 0)
329 {
330 return NULL;
331 }
332
333 gzFile gz_file = gzdopen (fd, "r");
334 if (gz_file == NULL)
335 {
336 return NULL;
337 }
338
339 FILE *file = fopencookie (gz_file, "r", io_functions);
340 return file;
341}
FILE * gvm_gzip_open_file_reader_fd(int fd)
Opens a gzip file as a FILE* stream for reading and decompression.
Definition compressutils.c:319
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:287
static int gz_file_close(void *cookie)
Close a gzip file.
Definition compressutils.c:271
static ssize_t gz_file_read(void *cookie, char *buffer, size_t buffer_size)
Read decompressed data from a gzip file.
Definition compressutils.c:256
void * gvm_compress_gzipheader(const void *src, unsigned long srclen, unsigned long *dstlen)
Compresses data in src buffer, gzip format compatible.
Definition compressutils.c:182
API related to data compression (gzip format.).