Re: tEXt Chunk text_length Ignored/Out-of-Bounds Read (libpng)

John Bowler <[email protected]> Thu, 30 Jul 2026 09:03:59 -0700
Newsgroups gmane.comp.graphics.png.devel
Message-ID <CAP7U39-Wk70WYNqPrq3U_fQOZm48h4i_Mv-XEgZEo_TJktcHZg@mail.gmail.com>
--===============1445396561684806264==
Content-Type: multipart/alternative; boundary="000000000000ee80250657d638c1"

--000000000000ee80250657d638c1
Content-Type: text/plain; charset="UTF-8"

I won't say that the text handling code is clean but the requirements for a
valid png_text_struct are unambiguous; see the comment immediately above
the definition of png_text_struct.  png_text_struct::text_length can be
regarded as a cache of the length but you will note there is no validation
of the png_text_struct within pngset.c (so far as I can remember) and
certainly not in the code path from the API (png_set_text()) to the
internal png_set_text_2().   The struct is a PITA internally because it's
not possible to use the actual contents of a tEXt chunk (which don't
include the '\0') and, instead, the chunk buffers have a spurious extra
byte allocated which is pre-assigned the value 0.  Yuck.

Thus in png_set_text() the application supplied png_text_struct, pointed to
by text_ptr is expected to be valid.  However in the actual implementation
the _length fields are never used...

The API has not changed since libpng 1.0 so we can be pretty sure that
there are apps out there which don't set the _length fields at all.

John Bowler <[email protected]>

--000000000000ee80250657d638c1
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I won&#39;t say that the text handling code is clean =
but the requirements for a valid png_text_struct are unambiguous; see the c=
omment immediately above the definition of png_text_struct.=C2=A0 png_text_=
struct::text_length can be regarded as a cache of the length but you will n=
ote there is no validation of the png_text_struct within pngset.c (so far a=
s I can remember) and certainly not in the code path from the API (png_set_=
text()) to the internal png_set_text_2().=C2=A0=C2=A0<span style=3D"backgro=
und-color:transparent">=C2=A0</span><span style=3D"background-color:transpa=
rent">The struct is a PITA internally because it&#39;s not possible to use =
the actual contents of a tEXt chunk (which don&#39;t include the &#39;\0&#3=
9;) and, instead, the chunk buffers have a spurious extra byte allocated wh=
ich is pre-assigned the value 0.=C2=A0 Yuck.</span></div><div><br></div><di=
v>Thus in png_set_text() the application supplied png_text_struct, pointed =
to by text_ptr is expected to be valid.=C2=A0 However in the actual impleme=
ntation the _length fields are never used...=C2=A0</div><div><br></div><div=
>The API has not changed since libpng 1.0 so we can be pretty sure that the=
re are apps out there which don&#39;t set the _length fields at all.</div><=
div><br></div><div><div dir=3D"ltr" class=3D"gmail_signature" data-smartmai=
l=3D"gmail_signature"><div dir=3D"ltr"><div><div>John Bowler &lt;<a href=3D=
"mailto:[email protected]" target=3D"_blank">[email protected]</a><font color=
=3D"#000120"></font><u></u>&gt;</div><div><br></div></div></div></div></div=
></div>

--000000000000ee80250657d638c1--


--===============1445396561684806264==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


--===============1445396561684806264==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
png-mng-implement mailing list
png-mng-implement-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/png-mng-implement

--===============1445396561684806264==--