Bug: Memory Leak in `zip_source_layered`
In the file `zip_source_crc`, it will return the value of the function call `zip_source_layered_create`.
However, `ctx` is a local variable; it is passed as an argument to `zip_source_layered_create`.
Also, the function `crc_read` is the callback function passed as an argument.
```c
zip_source_t *
zip_source_crc_create(zip_source_t *src, int validate, zip_error_t *error) {
struct crc_context *ctx;
if (src == NULL) {
zip_error_set(error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) {
zip_error_set(error, ZIP_ER_MEMORY, 0);
return NULL;
}
// ..
return zip_source_layered_create(src, crc_read, ctx, error);
}
```
However, the function may failed!
```c
zip_source_t *
zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error) {
zip_source_t *zs;
zip_int64_t lower_supports, supports;
lower_supports = zip_source_supports(src);
supports = cb(src, ud, &lower_supports, sizeof(lower_supports), ZIP_SOURCE_SUPPORTS);
if (supports < 0) {
zip_error_set(error,ZIP_ER_INVAL, 0); /* Initialize in case cb doesn't return valid error. */
// ================= the callback will free ud only if the last argu is ZIP_SOURCE_FREE
// leak at here ==========
cb(src, ud, error, sizeof(*error), ZIP_SOURCE_ERROR);
return NULL;
}
if ((zs = _zip_source_new(error)) == NULL) {
// ================= the callback will free ud only if the last argu is ZIP_SOURCE_FREE
// leak at here ==========
return NULL;
}
// ..
/* Layered sources can't support writing, since we currently have no use case. If we want to revisit this, we have to define how the two sources interact. */
zs->supports &= ~(ZIP_SOURCE_SUPPORTS_WRITABLE & ~ZIP_SOURCE_SUPPORTS_SEEKABLE);
return zs;
}
```
1 条评论