-
Notifications
You must be signed in to change notification settings - Fork 638
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
code cleanup: chunk lengths and allocation limits #646
code cleanup: chunk lengths and allocation limits #646
Conversation
Internal changes only. Move chunk length checks to fewer places: Change png_struct::user_chunk_malloc_max to always have a non-zero value in order to avoid the need to check for zero in multiple places. Add png_chunk_max(png_ptr), a function like macro defined in pngpriv.h which expresses all the previous checks on the various USER_LIMITS and system limitations. Replace the code which implemented such checks with png_chunk_max. Move the malloc limit length check in png_read_chunk_header to png_handle_chunk and make it conditional on the chunk type. Progressive reader: call png_read_chunk_header. Corect the handling for the pHYs. Signed-off-by: John Bowler <jbowler@acm.org>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few FYI's and a thumb down; see my full review.
Signed-off-by: John Bowler <jbowler@acm.org>
I just pushed the changes. Not a part of this change but getting rid of PNG_MAXSEG_64K, plus PNG_SMALL_SIZE_T and requiring (unsigned int) (which is what uInt is) be at least 32 bits would simplify the whole zlib decompression code; at present z_stream::avail_in is a uInt (as is IDAT_read_size) and ZLIB_IO_MAX is just (uInt)-1 so the decompression code has to loop just in case uInt (hence unsigned int) is too small. IDAT_read_size hasn't been changed since 2013. |
If my understanding of your statement is correct (or, if it isn't, please correct me) you are implying that the 16-bit support, in which |
Broadly my suggestion is to require INT_MAX and SIZE_MAX (only available from C99 on) to be at least PNG_UINT_32_MAX. The PNG_SMALL_SIZE_T mess arises because C90 does not define SIZE_MAX and PNG_SIZE_MAX is therefore no valid in a pre-processor statement. So PNG_SMALL_SIZE_T has to get set either by the magic "known compilers" stuff at starting at line 530 of pngconf.h or by definition in CFLAGS. A minimal change, without going to C99+, is to #error out if PNG_SMALL_SIZE_T is defined and then also if UINT_MAX is less than PNG_UINT_32_MAX. Similarly the setting of PNG_MAX_MALLOC_64K at line 436 of pngpriv.h would be changed to a #error. If that goes into a release and no one complains then the next step would be to simplify the code and put in runtime checks on PNG_SIZE_MAX and ZLIB_IO_MAX just to be safe. |
We should start using C99's stdint.h (if not C99 or newer, entirely) in libpng18. |
That's another powerful argument for C23: https://en.cppreference.com/w/c/language/typeof libpng users can't be expected to change their own code from using So all we can do is change pngconf.h to define all the png_ types in terms of Easy to do in libpng-1.8. Could be done in libpng-1.6 by requiring The same applies to zlib users. We have to use uInt to guarantee no truncation prior to C23. It's part of the legacy pre-stdint world and API compatibility and is one good example of where zlib-ng gets it wrong:
The avail_in and avail_out parameters should be But we, as users of zlib, don't need to know any of this:
That expression is a compile time constant, so some compilers will warn, but it's necessary with zlib_ng because the decompressed output of a PNG is currently limited only by (size_t) on most systems so can be larger than |
Let's take it slowly. We haven't even gone beyond C89 yet. (Which, by the way, we should.) One thing is rather clear to me: in libpng18, we can and we should take for granted the availability of All of the above, and maybe even more, can be compiled with |
Internal changes only.
Move chunk length checks to fewer places:
Change png_struct::user_chunk_malloc_max to always have a non-zero value
in order to avoid the need to check for zero in multiple places.
Add png_chunk_max(png_ptr), a function like macro defined in pngpriv.h
which expresses all the previous checks on the various USER_LIMITS and
system limitations. Replace the code which implemented such checks with
png_chunk_max.
Move the malloc limit length check in png_read_chunk_header to
png_handle_chunk and make it conditional on the chunk type.
Progressive reader: call png_read_chunk_header.
Corect the handling for the pHYs.
Signed-off-by: John Bowler jbowler@acm.org