Greenbone Vulnerability Management Libraries 22.18.1
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
40void *
41gvm_compress (const void *src, unsigned long srclen, unsigned long *dstlen)
42{
43 unsigned long buflen = srclen * 2;
44
45 if (src == NULL || dstlen == NULL)
46 return NULL;
47
48 if (buflen < 30)
49 buflen = 30;
50
51 while (1)
52 {
53 int err;
54 void *buffer;
55 z_stream strm;
56
57 /* Initialize deflate state */
58 strm.zalloc = Z_NULL;
59 strm.zfree = Z_NULL;
60 strm.opaque = Z_NULL;
61 strm.avail_in = srclen;
62#ifdef z_const
63 strm.next_in = src;
64#else
65 /* Workaround for older zlib. */
66 strm.next_in = (void *) src;
67#endif
68 if (deflateInit (&strm, Z_DEFAULT_COMPRESSION) != Z_OK)
69 return NULL;
70
71 buffer = g_malloc0 (buflen);
72 strm.avail_out = buflen;
73 strm.next_out = buffer;
74
75 err = deflate (&strm, Z_SYNC_FLUSH);
76 deflateEnd (&strm);
77 switch (err)
78 {
79 case Z_OK:
80 case Z_STREAM_END:
81 if (strm.avail_out != 0)
82 {
83 *dstlen = strm.total_out;
84 return buffer;
85 }
86 /* Fallthrough. */
87 case Z_BUF_ERROR:
88 g_free (buffer);
89 buflen *= 2;
90 break;
91
92 default:
93 g_free (buffer);
94 return NULL;
95 }
96 }
97}
98
108void *
109gvm_uncompress (const void *src, unsigned long srclen, unsigned long *dstlen)
110{
111 unsigned long buflen = srclen * 2;
112
113 if (src == NULL || dstlen == NULL)
114 return NULL;
115
116 while (1)
117 {
118 int err;
119 void *buffer;
120 z_stream strm;
121
122 /* Initialize inflate state */
123 strm.zalloc = Z_NULL;
124 strm.zfree = Z_NULL;
125 strm.opaque = Z_NULL;
126 strm.avail_in = srclen;
127#ifdef z_const
128 strm.next_in = src;
129#else
130 /* Workaround for older zlib. */
131 strm.next_in = (void *) src;
132#endif
133 /*
134 * From: http://www.zlib.net/manual.html
135 * Add 32 to windowBits to enable zlib and gzip decoding with automatic
136 * header detection.
137 */
138 if (inflateInit2 (&strm, 15 + 32) != Z_OK)
139 return NULL;
140
141 buffer = g_malloc0 (buflen);
142 strm.avail_out = buflen;
143 strm.next_out = buffer;
144
145 err = inflate (&strm, Z_SYNC_FLUSH);
146 inflateEnd (&strm);
147 switch (err)
148 {
149 case Z_OK:
150 case Z_STREAM_END:
151 if (strm.avail_out != 0)
152 {
153 *dstlen = strm.total_out;
154 return buffer;
155 }
156 /* Fallthrough. */
157 case Z_BUF_ERROR:
158 g_free (buffer);
159 buflen *= 2;
160 break;
161
162 default:
163 g_free (buffer);
164 return NULL;
165 }
166 }
167}
168
178void *
179gvm_compress_gzipheader (const void *src, unsigned long srclen,
180 unsigned long *dstlen)
181{
182 unsigned long buflen = srclen * 2;
183 int windowsBits = 15;
184 int GZIP_ENCODING = 16;
185
186 if (src == NULL || dstlen == NULL)
187 return NULL;
188
189 if (buflen < 30)
190 buflen = 30;
191
192 while (1)
193 {
194 int err;
195 void *buffer;
196 z_stream strm;
197
198 /* Initialize deflate state */
199 strm.zalloc = Z_NULL;
200 strm.zfree = Z_NULL;
201 strm.opaque = Z_NULL;
202 strm.avail_in = srclen;
203#ifdef z_const
204 strm.next_in = src;
205#else
206 /* Workaround for older zlib. */
207 strm.next_in = (void *) src;
208#endif
209
210 if (deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
211 windowsBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY)
212 != Z_OK)
213 return NULL;
214
215 buffer = g_malloc0 (buflen);
216 strm.avail_out = buflen;
217 strm.next_out = buffer;
218
219 err = deflate (&strm, Z_FINISH);
220 deflateEnd (&strm);
221 switch (err)
222 {
223 case Z_OK:
224 case Z_STREAM_END:
225 if (strm.avail_out != 0)
226 {
227 *dstlen = strm.total_out;
228 return buffer;
229 }
230 /* Fallthrough. */
231 case Z_BUF_ERROR:
232 g_free (buffer);
233 buflen *= 2;
234 break;
235
236 default:
237 g_free (buffer);
238 return NULL;
239 }
240 }
241}
242
252static ssize_t
253gz_file_read (void *cookie, char *buffer, size_t buffer_size)
254{
255 gzFile gz_file = cookie;
256
257 return gzread (gz_file, buffer, buffer_size);
258}
259
267static int
268gz_file_close (void *cookie)
269{
270 gzFile gz_file = cookie;
271
272 return gzclose (gz_file);
273 ;
274}
275
283FILE *
285{
286 static cookie_io_functions_t io_functions = {
287 .read = gz_file_read,
288 .write = NULL,
289 .seek = NULL,
290 .close = gz_file_close,
291 };
292
293 if (path == NULL)
294 {
295 return NULL;
296 }
297
298 gzFile gz_file = gzopen (path, "r");
299 if (gz_file == NULL)
300 {
301 return NULL;
302 }
303
304 FILE *file = fopencookie (gz_file, "r", io_functions);
305 return file;
306}
307
315FILE *
317{
318 static cookie_io_functions_t io_functions = {
319 .read = gz_file_read,
320 .write = NULL,
321 .seek = NULL,
322 .close = gz_file_close,
323 };
324
325 if (fd < 0)
326 {
327 return NULL;
328 }
329
330 gzFile gz_file = gzdopen (fd, "r");
331 if (gz_file == NULL)
332 {
333 return NULL;
334 }
335
336 FILE *file = fopencookie (gz_file, "r", io_functions);
337 return file;
338}
FILE * gvm_gzip_open_file_reader_fd(int fd)
Opens a gzip file as a FILE* stream for reading and decompression.
Definition compressutils.c:316
void * gvm_uncompress(const void *src, unsigned long srclen, unsigned long *dstlen)
Uncompresses data in src buffer.
Definition compressutils.c:109
void * gvm_compress(const void *src, unsigned long srclen, unsigned long *dstlen)
Compresses data in src buffer.
Definition compressutils.c:41
FILE * gvm_gzip_open_file_reader(const char *path)
Opens a gzip file as a FILE* stream for reading and decompression.
Definition compressutils.c:284
static int gz_file_close(void *cookie)
Close a gzip file.
Definition compressutils.c:268
static ssize_t gz_file_read(void *cookie, char *buffer, size_t buffer_size)
Read decompressed data from a gzip file.
Definition compressutils.c:253
void * gvm_compress_gzipheader(const void *src, unsigned long srclen, unsigned long *dstlen)
Compresses data in src buffer, gzip format compatible.
Definition compressutils.c:179
API related to data compression (gzip format.)