Re: libformw: field_buffer() segfaults on a field from dup_field()/link_field()

Thomas Dickey <[email protected]> Mon, 3 Aug 2026 15:20:19 -0400
Newsgroups gmane.comp.lib.ncurses.bugs
Message-ID <[email protected]>
--IWBQR15JbTnGlh2G
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Aug 03, 2026 at 02:05:18PM +0300, Serhiy Storchaka wrote:
> field_buffer() dereferences a NULL pointer for any field created by
> dup_field() or link_field(), when linked against libformw.  The narrow
> libform is not affected, and only the read side fails: set_field_buffer()
> and post_form() work on such a field, and calling set_field_buffer() first
> does not help.
>=20
> ncurses 6.6.20251231 (Debian libncursesw6 6.6+20251231-1),
> Linux 7.0.0 x86_64, gcc 15.2.0.
>=20
>   #include <form.h>
>   #include <locale.h>
>   #include <stdio.h>
>=20
>   int
>   main(void)
>   {
>       setlocale(LC_ALL, "");
>       initscr();
>       FIELD *orig =3D new_field(1, 10, 0, 0, 0, 0);
>       set_field_buffer(orig, 0, "hello");
>       FIELD *copy =3D dup_field(orig, 1, 0);
>       endwin();
>       printf("orig: %s\n", field_buffer(orig, 0));
>       printf("dup:  %s\n", field_buffer(copy, 0));   /* SIGSEGV here */
>       return 0;
>   }
>=20
>   $ gcc $(pkg-config --cflags formw ncursesw) t.c -o t \
>         $(pkg-config --libs formw ncursesw)
>   $ ./t
>   orig: hello
>   Segmentation fault
>   #0  field_buffer () from /usr/lib/x86_64-linux-gnu/libformw.so.6
>=20
> new_field() allocates the per-field rendering state:
>=20
>     fld_def.c:307:  New_Field->working =3D newpad(1, Buffer_Length(New_Fi=
eld)
> + 1);
>     fld_def.c:308:  New_Field->expanded =3D typeCalloc(char *, 1 +
> (unsigned)nbuf);
>=20
> dup_field() and link_field() start from *_nc_Default_Field, where both are
> NULL, and never allocate them.  A NULL 'working' is repaired by accident,
> since set_field_buffer() reallocates it when wresize() fails
> (frm_driver.c:4800-4804), but nothing repairs 'expanded', and field_buffe=
r()
> indexes it unconditionally:
>=20
>     frm_driver.c:4900:  if (field->expanded[buffer] !=3D NULL)
>=20
> test/dup_field.c never calls field_buffer() on the duplicated field, which
> is
> probably why this has gone unnoticed.
>=20
> No patch, as I cannot tell whether you would rather allocate the state in
> dup_field()/link_field() or have field_buffer() allocate it on demand.

I'll probably do the latter (thanks)

--=20
Thomas E. Dickey <[email protected]>
https://invisible-island.net

--IWBQR15JbTnGlh2G
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQGzBAABCgAdFiEEGYgtkt2kxADCLA1WzCr0RyFnvgMFAmpw6fMACgkQzCr0RyFn
vgNWXAwAn88eKrzy5ISzs/OuKoQpZ5dRcExQ/tNFo2KY2vJKOhibf3R6xcLuU3Qt
9u6D/ivv4OniHGS1UfHX1yzIcn8BG0l6xUYTU1RHi2XoqCRPNsHobBYyys/QcJ0T
bHSm+EBHvcHZhmuCCkW0vu9hgLCpOVY1BYb8t/b9hYXnVmM0FO5t1c488ZH01ycY
atF0jXrX8pQePRqlpC4YZCFy0psjFkOegK9FyJWJNG1xqZOtV933FUjAFeOgvPx/
aXw8EjE2y5s6+FWwXx8k82F0xseHVwbWIpLHCgcK8GZ9CUcH76Bo/4r+2p0k8MPN
5ppLd+dyHjQH9f6F9lGJJYRPCbluFFBuXyIzPgcYva7cY/O/0gxW7WXh82lBOw8h
Xcuy7mW9e0jmtzYZIjYV5SBDhPEjjYt6brPR7rAJ4zb6wtD06ospI158dW9zxns+
UOZuncEm1VIxkwYb2TpQwS71LOnyOzavjiZIVPkT7Uhiba2Oa7xR/iPp72zB8cS7
wPArZPFb
=MRP1
-----END PGP SIGNATURE-----

--IWBQR15JbTnGlh2G--