HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
pnggroup
libpng
C2015–2025
pnggroup / libpng

libpng

LIBPNG: Portable Network Graphics support, official libpng repository

8Distinct people
10Mentions
0Explicit recommenders
1.7KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

LIBPNG: Portable Network Graphics support, official libpng repository

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 5:04:57 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year10 dated mentions

Observed mentions: 2015-11-14 20:47:50 UTC to 2025-06-25 14:56:20 UTC.

01232015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20152016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC202
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC000
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC312
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC101
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC000
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC101
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101

What Hacker News says

10 sources
libpng was written before x86 had SIMD. If you look at how it writes loops, something that stands out is that the C style is often one that modern compilers can't auto-vectorize even if they tried very hard to, such as https://github.com/pnggroup/libpng/blob/c1cc0f3f4c3d4abd11ca... IMHO you need a lot of asterisks*** when you're advertising language comparisons against reference C that was optimized in the 1990's. edit: (That code snippet simply inflates an array of bits into an array of the matching bytes (0x00 or 0xff)).
In Memory-safe PNG decoders now outperform C PNG libraries
These might change your mind on reliability: https://github.com/glennrp/libpng/issues ; http://www.libpng.org/pub/png/libpng.html section "Security and Crash Bugs in Older Versions"; https://www.cvedetails.com/vulnerability-list/vendor_id-7294... Regarding performance, I already lost the game before it started because I'm writing Java. If I wanted to squeeze CPU time, I would be writing C/C++/asm. So I decided to aim for conciseness and reliability instead of the endless stream of vulnerabilities.
In Hello, PNG
There are three variants of option 2: - 2a: Use a new ancillary chunk (the OP's solution, here atCh) - 2b: Use officially dedicated PNG chunks (tEXt, zTXt, iTXt; draw.io/diagrams.net approach) - 2c: Put extra data to IDAT after the last DEFLATE block (most famously used by HTML-PNG polyglots, common in size-limited JavaScript demos) I think 2c is most robust among those options, because to my knowledge implementations that recompress IDAT without actual transcoding are rare. 2c does result in some libpng warnings [1] but doesn't seem to cause real-world issues. Also, special tooling requirement of option 2 can be slightly reduced by adopting ZIP approach: you can put magic bytes that are long enough and unlikely to appear by chance, so the reader can simply look for those bytes instead of parsing PNG chunks. This approach is most appropri
Read the rest
ate for options 2a and 2b (IDAT can be splitted, so there is no real guarantee that magic bytes remain intact) and it is recommended to reuse the existing PNG chunk structure, so that first 4 bytes of magic bytes are also PNG chunk types. It wouldn't fix the writer complexity though. [1] For example, https://github.com/glennrp/libpng/blob/a37d483/pngpread.c#L7...
In A new protocol and tool for PNG file attachments
Right, so the announcement is kind of vague; let's see what's actually going on. Here are the recent commits to libpng: https://github.com/glennrp/libpng/commits/libpng16 The first/latest one ("avoid potential pointer overflow") sounds scary, but I believe it's just about the pathological case where the library is handed (valid) buffers that extend to only a few bytes away from the maximum possible value (i.e. 0xfffff...). If your OS does this, it probably shouldn't. Going down the list, there are three relevant-looking commits. Listed in chronological order: [libpng16] Reject attempt to write over-length PLTE chunk https://github.com/glennrp/libpng/commit/81f44665cce4cb1373f... [libpng16] Prevent reading over-length PLTE chunk (Cosmin Truta). https://github.com/glennrp/libpng/commit/a901eb3ce6087e0afee... [libpng16] Silently truncate
Read the rest
over-length PLTE chunk while reading. https://github.com/glennrp/libpng/commit/1bef8e97995c3312366... - The first one only substantively changes png_write_PLTE, so it could only be an issue for applications that actually write out PNGs. It changes a check on the ‘num_pal’ argument from a hardcoded 256, aka PNG_MAX_PALETTE_LENGTH, to be based on the bit depth. The png_write_PLTE function is internal and called only from png_write_info, which passes it ‘info_ptr->palette’ and ‘info_ptr->num_palette’ as ‘palette’ and ‘num_pal’, respectively. - The second one confusingly changes png_write_PLTE again, but just to rename a variable. The substantive change is a similar check on an argument to png_set_PLTE, which is a public function and, incidentally, the only thing that can set ‘info_ptr->num_palette’, unless the application accesses it directly, which is deprecated. (Thus, outside of the deprecated case, it should ensure that the behavior change in the previous patch never actually gets exercised.) - The third one adds yet another check, to png_handle_PLTE, which is called when reading a PLTE chunk in a PNG file - this time, the variable is called ‘num’. After the check, ‘num’ is used to fill an array of size PNG_MAX_PALETTE_LENGTH - but there was already an earlier check for the length being too much for that, in which case it may longjmp out of the function with png_chunk_error or just return. png_handle_PLTE then calls png_set_PLTE with the same argument, so, in lieu of the added check, the previous commit’s check would still trigger and fail the image load. The new check just changes an error into something the library might be able to recover from. So the second commit is the important one, and the third demonstrates how png_set_PLTE can be called while reading a PNG with a size argument greater than appropriate for the bit depth, but still <= PNG_MAX_PALETTE_LENGTH. What happens then? The oss-security post says: > Some applications might read the bit depth from the IHDR chunk and allocate memory for a 2^N entry palette, while libpng can return a palette with up to 256 entries even when the bit depth is less than 8. So are only applications that do something odd affected? The png_get_PLTE function gives the client the actual num_palette value as an out argument, so any client that uses that to size buffers wouldn’t be affected; nor would one that hardcoded 256 or PNG_MAX_PALETTE_LENGTH. For example, Skia does the latter in SkImageDecoder_libpng.cpp. Are there any libpng-internal uses that could be affected? I grepped for ‘->(num_)?palette\b’. TLDR: I don’t think so, but if you want the pointless detail, among other less interesting uses were: /* Report invalid palette index; added at libng-1.5.10 */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_palette_max > png_ptr->num_palette) num_palette being too high could only make this fail, so it doesn’t matter. png_image_read_header uses it to set image->colormap_entries, which has its own long list of uses. I think this is then used (by the application, via PNG_IMAGE_COLORMAP_SIZE) to determine the size of the colormap buffer, but there may be an issue somewhere. png_image_read_colormap uses it to generate actual color map data, but this is not obviously dependent on the bit depth, and checked against image->colormap_entries (…in case it changed from earlier?). png_set_quantize uses a user-specified num_palette value and in any case is not important functionality. Some PNG_COMPOSE code uses num_palette to write to palette; not a problem… png_do_expand_palette just looks up entries in palette (png_ptr->palette) by byte-sized indices without checking anything. The palette buffer must be at least 256 entries long, or else it will read out of bounds, which is presumably why ->palette is only set here: /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead * of num_palette entries, in case of an invalid PNG file or incorrect * call to png_set_PLTE() with too-large sample values. */ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); (it’s set differently in the dither case, which I don’t think is relevant?) Anyway, it’s not affected by this. png_handle_tRNS and png_handle_hIST have separate arrays whose count is expected to be <= and ==, respectively, num_palette. - For trans, the ‘trans_alpha’ buffer itself is always PNG_MAX_PALETTE_LENGTH sized, so there can be no overflow there; it also sets info_ptr->num_trans. This can affect the application if it uses png_get_tRNS. - The hist buffer is also always maximum size and doesn’t have a separate length field, so it’s covered by me checking uses of num_palette. png_do_check_palette_indexes checks the bit-depth invariant separately. hIST again in pngwrite.c and pngwutil.c, nothing else interesting in those files. I think num_trans is safe in the same way, but I haven’t looked as closely.
In CVE-2015-8126: Multiple buffer overflows in libpng

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.