Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose zlib limited output buffer size functionality. #592

Closed
wants to merge 1 commit into from

Conversation

seriyps
Copy link
Contributor

@seriyps seriyps commented Jan 19, 2015

This functionality may be useful for compressed streams with high compression ratio (in case of gzip it may be up to x1000), when small amount of compressed input will produce large amount of uncompressed output. This may lead to DoS attacks, because server easily goes out of memory.

Example of such high compression ratio stream:

dd if=/dev/zero of=sparse.bin bs=1MB count=100 # 100mb of zeroes
gzip sparse.bin  # 95kb sparse.bin.gz
$ erl
> {ok, Compressed} = file:read_file("sparse.bin.gz"),
> 97082 = size(Compressed),
> Uncompressed = zlib:gunzip(Compressed),
> 100000000 = iolist_size(Uncompressed).

Imagine HTTP client, which download such Content-Encoding: gzip stream from remote WWW host.

So, suggested solution will look like this:

walk(Compressed, Handler) ->
    Z = zlib:open(),
    zlib:inflateInit(Z),
    % Limit single uncompressed chunk size to 512kb
    zlib:setBufSize(Z, 512 * 1024),
    loop(Z, Handler, zlib:inflateChunk(Z, Compressed)),
    zlib:inflateEnd(Z),
    zlib:close(Z).

loop(Z, Handler, {more, Uncompressed}) ->
    % iolist_size(Uncompressed) =< 512 kb
    Handler(Uncompressed),
    loop(Z, Handler, zlib:inflateChunk(Z));
loop(Z, Handler, Uncompressed) ->
    % iolist_size(Uncompressed) =< 512 kb
    Handler(Uncompressed).

And yes, it uses existing zlib:setBufSize/2 to configure output chunk size.

@OTP-Maintainer
Copy link

The summary line of the commit message is too long and/or ends with a "."
Make sure the whole message follows the guidelines here: https://github.com/erlang/otp/wiki/Writing-good-commit-messages.

Bad message: Expose zlib limited output buffer size functionality.


I am a script, I am not human


@seriyps
Copy link
Contributor Author

seriyps commented Jan 19, 2015

Fixed

@nox
Copy link
Contributor

nox commented Jan 20, 2015

You left a typo in the commit message: "functiomality". Nice feature, otherwise.

@seriyps
Copy link
Contributor Author

seriyps commented Jan 20, 2015

@nox oups! Fixed.

@seriyps seriyps force-pushed the zlib-inflate-bound branch 2 times, most recently from aa0a5c3 to ab4fb5f Compare January 20, 2015 18:00
@OTP-Maintainer
Copy link

Patch has passed first testings and has been assigned to be reviewed


I am a script, I am not human


@essen
Copy link
Contributor

essen commented Jan 26, 2015

+1.

@bjorng
Copy link
Contributor

bjorng commented Feb 12, 2015

Thanks, looks good, but I have a few comments about style. I have added my comments directly to the commit.

This functionality may be useful for compressed streams with high
compression ratio (in case of gzip it may be up to x1000), when
small amount of compressed data will produce large amount of
uncompressed output. This may lead to DoS attacks, because
server easily goes out of memory.

Example of such high compression ratio stream:
```
dd if=/dev/zero of=sparse.bin bs=1MB count=100 # 100mb of zeroes
gzip sparse.bin  # 95kb sparse.bin.gz
$ erl
> {ok, Compressed} = file:read_file("sparse.bin.gz"),
> 97082 = size(Compressed),
> Uncompressed = zlib:gunzip(Compressed),
> 100000000 = iolist_size(Uncompressed).
```
@seriyps
Copy link
Contributor Author

seriyps commented Feb 12, 2015

Fixed

@OTP-Maintainer
Copy link

Patch has passed first testings and has been assigned to be reviewed


I am a script, I am not human


@essen
Copy link
Contributor

essen commented Mar 4, 2015

Will this make it into OTP 18?

@proxyles
Copy link
Contributor

proxyles commented Mar 5, 2015

@essen that is the plan. If it pass the tests

@mworrell
Copy link

mworrell commented Mar 6, 2015

Great, this patch is exactly what I need to support gzip decoding in Zotonic. 👍

@proxyles
Copy link
Contributor

Merged to master

@proxyles proxyles closed this Mar 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants