OpenCoverage

c_zlib.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/comp/c_zlib.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.-
3 *-
4 * Licensed under the OpenSSL license (the "License"). You may not use-
5 * this file except in compliance with the License. You can obtain a copy-
6 * in the file LICENSE in the source distribution or at-
7 * https://www.openssl.org/source/license.html-
8 */-
9-
10#include <stdio.h>-
11#include <stdlib.h>-
12#include <string.h>-
13#include <openssl/objects.h>-
14#include "internal/comp.h"-
15#include <openssl/err.h>-
16#include "internal/cryptlib_int.h"-
17#include "internal/bio.h"-
18#include "comp_lcl.h"-
19-
20COMP_METHOD *COMP_zlib(void);-
21-
22static COMP_METHOD zlib_method_nozlib = {-
23 NID_undef,-
24 "(undef)",-
25 NULL,-
26 NULL,-
27 NULL,-
28 NULL,-
29};-
30-
31#ifndef ZLIB-
32# undef ZLIB_SHARED-
33#else-
34-
35# include <zlib.h>-
36-
37static int zlib_stateful_init(COMP_CTX *ctx);-
38static void zlib_stateful_finish(COMP_CTX *ctx);-
39static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,-
40 unsigned int olen, unsigned char *in,-
41 unsigned int ilen);-
42static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,-
43 unsigned int olen, unsigned char *in,-
44 unsigned int ilen);-
45-
46/* memory allocations functions for zlib initialisation */-
47static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)-
48{-
49 void *p;-
50-
51 p = OPENSSL_zalloc(no * size);-
52 return p;-
53}-
54-
55static void zlib_zfree(void *opaque, void *address)-
56{-
57 OPENSSL_free(address);-
58}-
59-
60-
61static COMP_METHOD zlib_stateful_method = {-
62 NID_zlib_compression,-
63 LN_zlib_compression,-
64 zlib_stateful_init,-
65 zlib_stateful_finish,-
66 zlib_stateful_compress_block,-
67 zlib_stateful_expand_block-
68};-
69-
70/*-
71 * When OpenSSL is built on Windows, we do not want to require that-
72 * the ZLIB.DLL be available in order for the OpenSSL DLLs to-
73 * work. Therefore, all ZLIB routines are loaded at run time-
74 * and we do not link to a .LIB file when ZLIB_SHARED is set.-
75 */-
76# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)-
77# include <windows.h>-
78# endif /* !(OPENSSL_SYS_WINDOWS ||-
79 * OPENSSL_SYS_WIN32) */-
80-
81# ifdef ZLIB_SHARED-
82# include "internal/dso.h"-
83-
84/* Function pointers */-
85typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,-
86 const Bytef *source, uLong sourceLen);-
87typedef int (*inflateEnd_ft) (z_streamp strm);-
88typedef int (*inflate_ft) (z_streamp strm, int flush);-
89typedef int (*inflateInit__ft) (z_streamp strm,-
90 const char *version, int stream_size);-
91typedef int (*deflateEnd_ft) (z_streamp strm);-
92typedef int (*deflate_ft) (z_streamp strm, int flush);-
93typedef int (*deflateInit__ft) (z_streamp strm, int level,-
94 const char *version, int stream_size);-
95typedef const char *(*zError__ft) (int err);-
96static compress_ft p_compress = NULL;-
97static inflateEnd_ft p_inflateEnd = NULL;-
98static inflate_ft p_inflate = NULL;-
99static inflateInit__ft p_inflateInit_ = NULL;-
100static deflateEnd_ft p_deflateEnd = NULL;-
101static deflate_ft p_deflate = NULL;-
102static deflateInit__ft p_deflateInit_ = NULL;-
103static zError__ft p_zError = NULL;-
104-
105static int zlib_loaded = 0; /* only attempt to init func pts once */-
106static DSO *zlib_dso = NULL;-
107-
108# define compress p_compress-
109# define inflateEnd p_inflateEnd-
110# define inflate p_inflate-
111# define inflateInit_ p_inflateInit_-
112# define deflateEnd p_deflateEnd-
113# define deflate p_deflate-
114# define deflateInit_ p_deflateInit_-
115# define zError p_zError-
116# endif /* ZLIB_SHARED */-
117-
118struct zlib_state {-
119 z_stream istream;-
120 z_stream ostream;-
121};-
122-
123static int zlib_stateful_init(COMP_CTX *ctx)-
124{-
125 int err;-
126 struct zlib_state *state = OPENSSL_zalloc(sizeof(*state));-
127-
128 if (state == NULL)-
129 goto err;-
130-
131 state->istream.zalloc = zlib_zalloc;-
132 state->istream.zfree = zlib_zfree;-
133 state->istream.opaque = Z_NULL;-
134 state->istream.next_in = Z_NULL;-
135 state->istream.next_out = Z_NULL;-
136 err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));-
137 if (err != Z_OK)-
138 goto err;-
139-
140 state->ostream.zalloc = zlib_zalloc;-
141 state->ostream.zfree = zlib_zfree;-
142 state->ostream.opaque = Z_NULL;-
143 state->ostream.next_in = Z_NULL;-
144 state->ostream.next_out = Z_NULL;-
145 err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,-
146 ZLIB_VERSION, sizeof(z_stream));-
147 if (err != Z_OK)-
148 goto err;-
149-
150 ctx->data = state;-
151 return 1;-
152 err:-
153 OPENSSL_free(state);-
154 return 0;-
155}-
156-
157static void zlib_stateful_finish(COMP_CTX *ctx)-
158{-
159 struct zlib_state *state = ctx->data;-
160 inflateEnd(&state->istream);-
161 deflateEnd(&state->ostream);-
162 OPENSSL_free(state);-
163}-
164-
165static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,-
166 unsigned int olen, unsigned char *in,-
167 unsigned int ilen)-
168{-
169 int err = Z_OK;-
170 struct zlib_state *state = ctx->data;-
171-
172 if (state == NULL)-
173 return -1;-
174-
175 state->ostream.next_in = in;-
176 state->ostream.avail_in = ilen;-
177 state->ostream.next_out = out;-
178 state->ostream.avail_out = olen;-
179 if (ilen > 0)-
180 err = deflate(&state->ostream, Z_SYNC_FLUSH);-
181 if (err != Z_OK)-
182 return -1;-
183 return olen - state->ostream.avail_out;-
184}-
185-
186static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,-
187 unsigned int olen, unsigned char *in,-
188 unsigned int ilen)-
189{-
190 int err = Z_OK;-
191 struct zlib_state *state = ctx->data;-
192-
193 if (state == NULL)-
194 return 0;-
195-
196 state->istream.next_in = in;-
197 state->istream.avail_in = ilen;-
198 state->istream.next_out = out;-
199 state->istream.avail_out = olen;-
200 if (ilen > 0)-
201 err = inflate(&state->istream, Z_SYNC_FLUSH);-
202 if (err != Z_OK)-
203 return -1;-
204 return olen - state->istream.avail_out;-
205}-
206-
207#endif-
208-
209COMP_METHOD *COMP_zlib(void)-
210{-
211 COMP_METHOD *meth = &zlib_method_nozlib;-
212-
213#ifdef ZLIB_SHARED-
214 /* LIBZ may be externally defined, and we should respect that value */-
215# ifndef LIBZ-
216# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)-
217# define LIBZ "ZLIB1"-
218# elif defined(OPENSSL_SYS_VMS)-
219# define LIBZ "LIBZ"-
220# else-
221# define LIBZ "z"-
222# endif-
223# endif-
224-
225 if (!zlib_loaded) {-
226 zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);-
227 if (zlib_dso != NULL) {-
228 p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");-
229 p_inflateEnd-
230 = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");-
231 p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");-
232 p_inflateInit_-
233 = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");-
234 p_deflateEnd-
235 = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");-
236 p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");-
237 p_deflateInit_-
238 = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");-
239 p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");-
240-
241 if (p_compress && p_inflateEnd && p_inflate-
242 && p_inflateInit_ && p_deflateEnd-
243 && p_deflate && p_deflateInit_ && p_zError)-
244 zlib_loaded++;-
245-
246 if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) {-
247 comp_zlib_cleanup_int();-
248 return meth;-
249 }-
250 if (zlib_loaded)-
251 meth = &zlib_stateful_method;-
252 }-
253 }-
254#endif-
255#if defined(ZLIB)-
256 meth = &zlib_stateful_method;-
257#endif-
258-
259 return meth;
executed 1958 times by 1 test: return meth;
Executed by:
  • libcrypto.so.1.1
1958
260}-
261-
262void comp_zlib_cleanup_int(void)-
263{-
264#ifdef ZLIB_SHARED-
265 DSO_free(zlib_dso);-
266 zlib_dso = NULL;-
267#endif-
268}-
269-
270#ifdef ZLIB-
271-
272/* Zlib based compression/decompression filter BIO */-
273-
274typedef struct {-
275 unsigned char *ibuf; /* Input buffer */-
276 int ibufsize; /* Buffer size */-
277 z_stream zin; /* Input decompress context */-
278 unsigned char *obuf; /* Output buffer */-
279 int obufsize; /* Output buffer size */-
280 unsigned char *optr; /* Position in output buffer */-
281 int ocount; /* Amount of data in output buffer */-
282 int odone; /* deflate EOF */-
283 int comp_level; /* Compression level to use */-
284 z_stream zout; /* Output compression context */-
285} BIO_ZLIB_CTX;-
286-
287# define ZLIB_DEFAULT_BUFSIZE 1024-
288-
289static int bio_zlib_new(BIO *bi);-
290static int bio_zlib_free(BIO *bi);-
291static int bio_zlib_read(BIO *b, char *out, int outl);-
292static int bio_zlib_write(BIO *b, const char *in, int inl);-
293static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);-
294static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);-
295-
296static const BIO_METHOD bio_meth_zlib = {-
297 BIO_TYPE_COMP,-
298 "zlib",-
299 /* TODO: Convert to new style write function */-
300 bwrite_conv,-
301 bio_zlib_write,-
302 /* TODO: Convert to new style read function */-
303 bread_conv,-
304 bio_zlib_read,-
305 NULL, /* bio_zlib_puts, */-
306 NULL, /* bio_zlib_gets, */-
307 bio_zlib_ctrl,-
308 bio_zlib_new,-
309 bio_zlib_free,-
310 bio_zlib_callback_ctrl-
311};-
312-
313const BIO_METHOD *BIO_f_zlib(void)-
314{-
315 return &bio_meth_zlib;-
316}-
317-
318static int bio_zlib_new(BIO *bi)-
319{-
320 BIO_ZLIB_CTX *ctx;-
321# ifdef ZLIB_SHARED-
322 (void)COMP_zlib();-
323 if (!zlib_loaded) {-
324 COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);-
325 return 0;-
326 }-
327# endif-
328 ctx = OPENSSL_zalloc(sizeof(*ctx));-
329 if (ctx == NULL) {-
330 COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);-
331 return 0;-
332 }-
333 ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;-
334 ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;-
335 ctx->zin.zalloc = Z_NULL;-
336 ctx->zin.zfree = Z_NULL;-
337 ctx->zout.zalloc = Z_NULL;-
338 ctx->zout.zfree = Z_NULL;-
339 ctx->comp_level = Z_DEFAULT_COMPRESSION;-
340 BIO_set_init(bi, 1);-
341 BIO_set_data(bi, ctx);-
342-
343 return 1;-
344}-
345-
346static int bio_zlib_free(BIO *bi)-
347{-
348 BIO_ZLIB_CTX *ctx;-
349 if (!bi)-
350 return 0;-
351 ctx = BIO_get_data(bi);-
352 if (ctx->ibuf) {-
353 /* Destroy decompress context */-
354 inflateEnd(&ctx->zin);-
355 OPENSSL_free(ctx->ibuf);-
356 }-
357 if (ctx->obuf) {-
358 /* Destroy compress context */-
359 deflateEnd(&ctx->zout);-
360 OPENSSL_free(ctx->obuf);-
361 }-
362 OPENSSL_free(ctx);-
363 BIO_set_data(bi, NULL);-
364 BIO_set_init(bi, 0);-
365-
366 return 1;-
367}-
368-
369static int bio_zlib_read(BIO *b, char *out, int outl)-
370{-
371 BIO_ZLIB_CTX *ctx;-
372 int ret;-
373 z_stream *zin;-
374 BIO *next = BIO_next(b);-
375-
376 if (!out || !outl)-
377 return 0;-
378 ctx = BIO_get_data(b);-
379 zin = &ctx->zin;-
380 BIO_clear_retry_flags(b);-
381 if (!ctx->ibuf) {-
382 ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);-
383 if (ctx->ibuf == NULL) {-
384 COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);-
385 return 0;-
386 }-
387 inflateInit(zin);-
388 zin->next_in = ctx->ibuf;-
389 zin->avail_in = 0;-
390 }-
391-
392 /* Copy output data directly to supplied buffer */-
393 zin->next_out = (unsigned char *)out;-
394 zin->avail_out = (unsigned int)outl;-
395 for (;;) {-
396 /* Decompress while data available */-
397 while (zin->avail_in) {-
398 ret = inflate(zin, 0);-
399 if ((ret != Z_OK) && (ret != Z_STREAM_END)) {-
400 COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);-
401 ERR_add_error_data(2, "zlib error:", zError(ret));-
402 return 0;-
403 }-
404 /* If EOF or we've read everything then return */-
405 if ((ret == Z_STREAM_END) || !zin->avail_out)-
406 return outl - zin->avail_out;-
407 }-
408-
409 /*-
410 * No data in input buffer try to read some in, if an error then-
411 * return the total data read.-
412 */-
413 ret = BIO_read(next, ctx->ibuf, ctx->ibufsize);-
414 if (ret <= 0) {-
415 /* Total data read */-
416 int tot = outl - zin->avail_out;-
417 BIO_copy_next_retry(b);-
418 if (ret < 0)-
419 return (tot > 0) ? tot : ret;-
420 return tot;-
421 }-
422 zin->avail_in = ret;-
423 zin->next_in = ctx->ibuf;-
424 }-
425}-
426-
427static int bio_zlib_write(BIO *b, const char *in, int inl)-
428{-
429 BIO_ZLIB_CTX *ctx;-
430 int ret;-
431 z_stream *zout;-
432 BIO *next = BIO_next(b);-
433-
434 if (!in || !inl)-
435 return 0;-
436 ctx = BIO_get_data(b);-
437 if (ctx->odone)-
438 return 0;-
439 zout = &ctx->zout;-
440 BIO_clear_retry_flags(b);-
441 if (!ctx->obuf) {-
442 ctx->obuf = OPENSSL_malloc(ctx->obufsize);-
443 /* Need error here */-
444 if (ctx->obuf == NULL) {-
445 COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);-
446 return 0;-
447 }-
448 ctx->optr = ctx->obuf;-
449 ctx->ocount = 0;-
450 deflateInit(zout, ctx->comp_level);-
451 zout->next_out = ctx->obuf;-
452 zout->avail_out = ctx->obufsize;-
453 }-
454 /* Obtain input data directly from supplied buffer */-
455 zout->next_in = (void *)in;-
456 zout->avail_in = inl;-
457 for (;;) {-
458 /* If data in output buffer write it first */-
459 while (ctx->ocount) {-
460 ret = BIO_write(next, ctx->optr, ctx->ocount);-
461 if (ret <= 0) {-
462 /* Total data written */-
463 int tot = inl - zout->avail_in;-
464 BIO_copy_next_retry(b);-
465 if (ret < 0)-
466 return (tot > 0) ? tot : ret;-
467 return tot;-
468 }-
469 ctx->optr += ret;-
470 ctx->ocount -= ret;-
471 }-
472-
473 /* Have we consumed all supplied data? */-
474 if (!zout->avail_in)-
475 return inl;-
476-
477 /* Compress some more */-
478-
479 /* Reset buffer */-
480 ctx->optr = ctx->obuf;-
481 zout->next_out = ctx->obuf;-
482 zout->avail_out = ctx->obufsize;-
483 /* Compress some more */-
484 ret = deflate(zout, 0);-
485 if (ret != Z_OK) {-
486 COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);-
487 ERR_add_error_data(2, "zlib error:", zError(ret));-
488 return 0;-
489 }-
490 ctx->ocount = ctx->obufsize - zout->avail_out;-
491 }-
492}-
493-
494static int bio_zlib_flush(BIO *b)-
495{-
496 BIO_ZLIB_CTX *ctx;-
497 int ret;-
498 z_stream *zout;-
499 BIO *next = BIO_next(b);-
500-
501 ctx = BIO_get_data(b);-
502 /* If no data written or already flush show success */-
503 if (!ctx->obuf || (ctx->odone && !ctx->ocount))-
504 return 1;-
505 zout = &ctx->zout;-
506 BIO_clear_retry_flags(b);-
507 /* No more input data */-
508 zout->next_in = NULL;-
509 zout->avail_in = 0;-
510 for (;;) {-
511 /* If data in output buffer write it first */-
512 while (ctx->ocount) {-
513 ret = BIO_write(next, ctx->optr, ctx->ocount);-
514 if (ret <= 0) {-
515 BIO_copy_next_retry(b);-
516 return ret;-
517 }-
518 ctx->optr += ret;-
519 ctx->ocount -= ret;-
520 }-
521 if (ctx->odone)-
522 return 1;-
523-
524 /* Compress some more */-
525-
526 /* Reset buffer */-
527 ctx->optr = ctx->obuf;-
528 zout->next_out = ctx->obuf;-
529 zout->avail_out = ctx->obufsize;-
530 /* Compress some more */-
531 ret = deflate(zout, Z_FINISH);-
532 if (ret == Z_STREAM_END)-
533 ctx->odone = 1;-
534 else if (ret != Z_OK) {-
535 COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);-
536 ERR_add_error_data(2, "zlib error:", zError(ret));-
537 return 0;-
538 }-
539 ctx->ocount = ctx->obufsize - zout->avail_out;-
540 }-
541}-
542-
543static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)-
544{-
545 BIO_ZLIB_CTX *ctx;-
546 int ret, *ip;-
547 int ibs, obs;-
548 BIO *next = BIO_next(b);-
549-
550 if (next == NULL)-
551 return 0;-
552 ctx = BIO_get_data(b);-
553 switch (cmd) {-
554-
555 case BIO_CTRL_RESET:-
556 ctx->ocount = 0;-
557 ctx->odone = 0;-
558 ret = 1;-
559 break;-
560-
561 case BIO_CTRL_FLUSH:-
562 ret = bio_zlib_flush(b);-
563 if (ret > 0)-
564 ret = BIO_flush(next);-
565 break;-
566-
567 case BIO_C_SET_BUFF_SIZE:-
568 ibs = -1;-
569 obs = -1;-
570 if (ptr != NULL) {-
571 ip = ptr;-
572 if (*ip == 0)-
573 ibs = (int)num;-
574 else-
575 obs = (int)num;-
576 } else {-
577 ibs = (int)num;-
578 obs = ibs;-
579 }-
580-
581 if (ibs != -1) {-
582 OPENSSL_free(ctx->ibuf);-
583 ctx->ibuf = NULL;-
584 ctx->ibufsize = ibs;-
585 }-
586-
587 if (obs != -1) {-
588 OPENSSL_free(ctx->obuf);-
589 ctx->obuf = NULL;-
590 ctx->obufsize = obs;-
591 }-
592 ret = 1;-
593 break;-
594-
595 case BIO_C_DO_STATE_MACHINE:-
596 BIO_clear_retry_flags(b);-
597 ret = BIO_ctrl(next, cmd, num, ptr);-
598 BIO_copy_next_retry(b);-
599 break;-
600-
601 default:-
602 ret = BIO_ctrl(next, cmd, num, ptr);-
603 break;-
604-
605 }-
606-
607 return ret;-
608}-
609-
610static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)-
611{-
612 BIO *next = BIO_next(b);-
613 if (next == NULL)-
614 return 0;-
615 return BIO_callback_ctrl(next, cmd, fp);-
616}-
617-
618#endif-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2