Control: retitle -1 screen: memory corruption when $TERM's total termcap length 
exceeds buffer => segfault or malloc SIGABRT
Control: found -1 4.9.0-4
Control: found -1 4.9.1-1
Control: tag   -1 = patch

Installed screen again, hit a segfault, reportbug said I have this open already.
Repro on bookworm/amd64 and sid/x32.

This time with some more interesting gubbins, hopefully,
because strace on bookworm ends with
-- >8 --
3234294 ioctl(1, TCGETS, 0x7fff4f414180) = -1 ENOTTY (Inappropriate ioctl for 
device)
3234294 access("/etc/terminfo/s/st-256color", R_OK) = 0
3234294 getuid()                        = 1000
3234294 setfsuid(1000)                  = 1000
3234294 getgid()                        = 100
3234294 setfsgid(100)                   = 100
3234294 openat(AT_FDCWD, "/etc/terminfo/s/st-256color", O_RDONLY) = 5
3234294 geteuid()                       = 1000
3234294 setfsuid(1000)                  = 1000
3234294 getegid()                       = 100
3234294 setfsgid(100)                   = 100
3234294 newfstatat(5, "", {st_mode=S_IFREG|0644, st_size=2565, ...}, 
AT_EMPTY_PATH) = 0
3234294 read(5, "\32\1(\0\35\0\17\0i\1W\6st-256color| simplet"..., 30720) = 2565
3234294 read(5, "", 27648)              = 0
3234294 close(5)                        = 0
3234294 ioctl(2, TCGETS, 0x7fff4f414180) = -1 ENOTTY (Inappropriate ioctl for 
device)
3234294 ioctl(2, TCGETS, 0x7fff4f414110) = -1 ENOTTY (Inappropriate ioctl for 
device)
3234294 writev(2, [{iov_base="corrupted size vs. prev_size", iov_len=28}, 
{iov_base="\n", iov_len=1}], 2) = 29
3234294 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
0) = 0x7feaabb5c000
3234294 rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
3234294 gettid()                        = 3234294
3234294 getpid()                        = 3234294
3234294 tgkill(3234294, 3234294, SIGABRT) = 0
3234294 --- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=3234294, 
si_uid=1000} ---
3234294 +++ killed by SIGABRT +++
-- >8 --
for the child and then the top-level process hangs
(well, it loops in pause() with ^C ignored; ^Z/^\ work normally).

Pretty sure this is a malloc sanity-check abort message?


On sid I just get "[screen caught signal 11. (core dumped)]" and no coredump.
No valgrind for x32 so whatever.


On bookworm for valgrind screen ls I get:
-- >8 --
==3274260== Memcheck, a memory error detector
==3274260== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==3274260== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==3274260== Command: screen ls
==3274260== 
==3274433== Invalid write of size 1
==3274433==    at 0x48468E4: strcpy (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x487E600: UnknownInlinedFun (string_fortified.h:79)
==3274433==    by 0x487E600: tgetstr_sp (lib_termcap.c:380)
==3274433==    by 0x135FDA: e_tgetstr (termcap.c:1505)
==3274433==    by 0x135FDA: InitTermcap (termcap.c:157)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b66 is 0 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid write of size 1
==3274433==    at 0x48468F6: strcpy (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x487E600: UnknownInlinedFun (string_fortified.h:79)
==3274433==    by 0x487E600: tgetstr_sp (lib_termcap.c:380)
==3274433==    by 0x135FDA: e_tgetstr (termcap.c:1505)
==3274433==    by 0x135FDA: InitTermcap (termcap.c:157)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b68 is 2 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x48467F4: __strlen_sse2 (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x487E60C: tgetstr_sp (lib_termcap.c:382)
==3274433==    by 0x135FDA: e_tgetstr (termcap.c:1505)
==3274433==    by 0x135FDA: InitTermcap (termcap.c:157)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b66 is 0 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x48467E2: __strlen_sse2 (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x487E60C: tgetstr_sp (lib_termcap.c:382)
==3274433==    by 0x135FDA: e_tgetstr (termcap.c:1505)
==3274433==    by 0x135FDA: InitTermcap (termcap.c:157)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b69 is 3 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x135E9F: InitTermcap (termcap.c:159)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b69 is 3 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x136912: InitTermcap (termcap.c:469)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23ba5 is 11 bytes before a block of size 7,952 alloc'd
==3274433==    at 0x48455EF: calloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x4879967: _nc_build_names (comp_captab.c:3285)
==3274433==    by 0x487A10A: _nc_find_type_entry (comp_hash.c:104)
==3274433==    by 0x487E453: tgetnum_sp (lib_termcap.c:300)
==3274433==    by 0x135FFF: e_tgetnum (termcap.c:1541)
==3274433==    by 0x135FFF: InitTermcap (termcap.c:154)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x48467F4: __strlen_sse2 (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x133A18: remap (termcap.c:528)
==3274433==    by 0x13695E: InitTermcap (termcap.c:478)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b66 is 0 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x13313C: findseq_ge (termcap.c:632)
==3274433==    by 0x133CE2: addmapseq (termcap.c:687)
==3274433==    by 0x133CE2: remap (termcap.c:562)
==3274433==    by 0x13695E: InitTermcap (termcap.c:478)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b66 is 0 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x4847A1D: memcpy@GLIBC_2.2.5 (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x133D94: UnknownInlinedFun (strings_fortified.h:25)
==3274433==    by 0x133D94: addmapseq (termcap.c:710)
==3274433==    by 0x133D94: remap (termcap.c:562)
==3274433==    by 0x13695E: InitTermcap (termcap.c:478)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b66 is 0 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x4847A10: memcpy@GLIBC_2.2.5 (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x133D94: UnknownInlinedFun (strings_fortified.h:25)
==3274433==    by 0x133D94: addmapseq (termcap.c:710)
==3274433==    by 0x133D94: remap (termcap.c:562)
==3274433==    by 0x13695E: InitTermcap (termcap.c:478)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b67 is 1 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x133ED9: addmapseq (termcap.c:733)
==3274433==    by 0x133ED9: remap (termcap.c:562)
==3274433==    by 0x13695E: InitTermcap (termcap.c:478)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b66 is 0 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 
==3274433== Invalid read of size 1
==3274433==    at 0x48467E2: __strlen_sse2 (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x133A18: remap (termcap.c:528)
==3274433==    by 0x13695E: InitTermcap (termcap.c:478)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433==  Address 0x4b23b69 is 3 bytes after a block of size 1,030 alloc'd
==3274433==    at 0x48407B4: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x135E29: InitTermcap (termcap.c:136)
==3274433==    by 0x112B28: main (screen.c:1390)
==3274433== 

valgrind: m_mallocfree.c:303 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' 
failed.
valgrind: Heap block lo/hi size mismatch: lo = 1104, hi = 9093149294164390459.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.


host stacktrace:
==3274433==    at 0x580429AA: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x58042AC7: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x58042C57: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x5804C708: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x5803B31A: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x58039A1E: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x5803E1F5: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x58038CF8: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x5800F063: ??? (in 
/usr/libexec/valgrind/memcheck-amd64-linux)
==3274433==    by 0x1002F02807: ???
==3274433==    by 0x1002DB5F2F: ???
==3274433==    by 0x1002DB5F17: ???
==3274433==    by 0x1002DB5F2F: ???
==3274433==    by 0x1C0F: ???
==3274433==    by 0x100200839F: ???

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 3274433)
==3274433==    at 0x48478F1: memcpy@GLIBC_2.2.5 (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3274433==    by 0x133D94: UnknownInlinedFun (strings_fortified.h:25)
==3274433==    by 0x133D94: addmapseq (termcap.c:710)
==3274433==    by 0x133D94: remap (termcap.c:562)
==3274433==    by 0x13695E: InitTermcap (termcap.c:478)
==3274433==    by 0x112B28: main (screen.c:1390)
client stack range: [0x1FFEFE5000 0x1FFF000FFF] client SP: 0x1FFEFFEA08
valgrind stack range: [0x1002CB6000 0x1002DB5FFF] top usage: 19208 of 1048576
-- >8 --
which confirms memory corruption.

Despite the suggestive name, termcap.c appears to be from screen:
 136   if ((D_tentry = (char *)malloc(TERMCAP_BUFSIZE + (extra_incap ? 
strlen(extra_incap) + 1 : 0))) == 0)
 ...
 145   tp = D_tentry;
 146   for (i = 0; i < T_N; i++) {
 148       switch(term[i].type) {
 156     case T_STR:
 157       D_tcs[i].str = e_tgetstr(term[i].tcname, &tp);

1497 static char * e_tgetstr(cap, tepp) char *cap; char **tepp; {
1502   char *tep;
1503   if ((tep = findcap(cap, tepp, 0)))
1504     return (*tep == '@') ? 0 : tep;
1505   return tgetstr(cap, tepp);

tgetstr(3) doesn't seem to say what the size /should/ be.

lib_termcap.c
342 NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx const char *id, char **area)
378                 if (area != 0
379                     && *area != 0) {
380                     _nc_STRCPY(*area, result, 1024);
381                     result = *area;
382                     *area += strlen(*area) + 1;

Which seems a little undercooked (TERMCAP_BUFSIZE is 1023), and GDBing to 380
  (gdb) p result
  $4 = 0x5555555e3f12 "\033[%i%p1%d;%p2%dH"
for "cm", then a few more, then the last call is for "la", and that crashes.
For "la" the result seems to be NULL, so afterward tp is "". 

Rebuilding screen with asan, I see
-- >8 --
$ strace -vs9999  -foss ./screen
^\Quit
$ eval "printf  %b $(grep 'write(2' ss | cut -c18- | sed 's/, [0-9]*)[ ]*=[ 
]*[0-9]*$//' | tr '\n' ' ')"
=================================================================
==3391667==ERROR: AddressSanitizer: heap-buffer-overflow on address 
0x519000000e86 at pc 0x559f9edd719a bp 0x7ffd78561dd0 sp 0x7ffd78561588
WRITE of size 7 at 0x519000000e86 thread T0
    #0 0x559f9edd7199 in strcpy 
(/home/nabijaczleweli/uwu/iselect/debian/screen-4.9.1/build/screen+0xde199) 
(BuildId: c61c99670bf01c54ae47da9eae7a493e6e27987e)
    #1 0x7f7bd4c17600  
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:79:10
    #2 0x7f7bd4c17600 in tgetstr_sp 
obj-wide/ncurses/../../ncurses/tinfo/lib_termcap.c:380:7
    #3 0x559f9ee95a77 in e_tgetstr build/../termcap.c:1505:10
    #4 0x559f9ee95a77 in InitTermcap build/../termcap.c:157:19
    #5 0x559f9ee32ab3 in main build/../screen.c:1390:9
    #6 0x7f7bd48e2249 in __libc_start_call_main 
csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #7 0x7f7bd48e2304 in __libc_start_main csu/../csu/libc-start.c:360:3
    #8 0x559f9ed50960 in _start 
(/home/nabijaczleweli/uwu/iselect/debian/screen-4.9.1/build/screen+0x57960) 
(BuildId: c61c99670bf01c54ae47da9eae7a493e6e27987e)

0x519000000e86 is located 0 bytes after 1030-byte region 
[0x519000000a80,0x519000000e86)
allocated by thread T0 here:
    #0 0x559f9edef75f in malloc 
(/home/nabijaczleweli/uwu/iselect/debian/screen-4.9.1/build/screen+0xf675f) 
(BuildId: c61c99670bf01c54ae47da9eae7a493e6e27987e)
    #1 0x559f9ee957ea in InitTermcap build/../termcap.c:136:27
    #2 0x559f9ee32ab3 in main build/../screen.c:1390:9
    #3 0x7f7bd48e2249 in __libc_start_call_main 
csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: heap-buffer-overflow 
(/home/nabijaczleweli/uwu/iselect/debian/screen-4.9.1/build/screen+0xde199) 
(BuildId: c61c99670bf01c54ae47da9eae7a493e6e27987e) in strcpy
Shadow bytes around the buggy address:
  0x519000000c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x519000000c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x519000000d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x519000000d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x519000000e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x519000000e80:[06]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x519000000f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x519000000f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x519000001000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x519000001080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x519000001100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==3391667==ABORTING
-- >8 --
so they definitely agree here.

This looks like a classic buffer overflow: since
  382                     *area += strlen(*area) + 1;
and with ltrace -l '*' -foll screen I can see the Area
  3413285 screen->malloc(1030) = 0x561401f95100
and the bumps
  3413285 <... tgetstr_sp resumed> ) = 0x561401f95100
  3413285 <... tgetstr resumed> , "") = "\033[%i%p1%d;%p2%dH"
(this has length 16, so we'd expect the next one to be +17, and whaddaya know)
  3413285 <... tgetstr_sp resumed> ) = 0x561401f95111
  3413285 <... tgetstr resumed> , "") = "\033[H"
and the last non-NULL result is
  3413285 <... tgetstr_sp resumed> ) = 0x561401f95556
  3413285 <... tgetstr resumed> , "") = "\033OD"

which is hex(561401f95556) - hex(561401f95100) = 1110 (+ sizeof("\e0D")),
which obviously blows the 1030.

turning line 1505 into return tgetstr(cap, NULL);
(since per tgetstr(3) under ncurses the buffer is auxiliary)
kinda works (after disabling asan, else use-after-free, as expected).

Turning line 136 into ...TERMCAP_BUFSIZE * 10... fully works, even under asan.

So:
1. where-ever TERMCAP_BUFSIZE=1023 came from, and what-ever it's good for,
   using it for this allocation is obviously wrong:
   ncurses does strlcpy(..., 1024) to it,
   so it must be 1024 for /every/ call to tgetstr() at /least/
2. this is presumably triggered by st-256color because it has more
   overall capability string volume than other teletypes?
   I'm not an expert on terminfo, but this is it:
     https://git.suckless.org/st/file/st.info.html
3. the easiest fix is probably to just allocate 10k,
   and to hell with it?
4. a more convoluted but a more correct fix is to tgetstr() to a stack 1k 
buffer,
   then just strdup the result, and free it later

I have implemented 4., and a patch (accd'g to dpkg-source --commit vs 4.9.1-1)
is included below. It passes asan and valgrind.

It doesn't pass msan, but this is unrelated to the patch since it also
happens with the original implementation regardless of $TERM.
Someone who understands screen (not me) should probably try running it
with msan and fix the use-after-free :)

Best,
--- screen-4.9.1.orig/display.c
+++ screen-4.9.1/display.c
@@ -334,6 +334,7 @@ struct mode *Mode;
 }
 
 
+extern struct term term[];  /* terminal capabilities */
 void
 FreeDisplay()
 {
@@ -357,9 +358,12 @@ FreeDisplay()
       fcntl(D_userfd, F_SETFL, 0);
     }
   freetty();
-  if (D_tentry)
-    free(D_tentry);
-  D_tentry = 0;
+  for (size_t i = 0; i < T_N; ++i)
+    if (term[i].type == T_STR && D_tcs[i].str)
+      {
+        free(D_tcs[i].str);
+        D_tcs[i].str = 0;
+      }
   if (D_processinputdata)
     free(D_processinputdata);
   D_processinputdata = 0;
--- screen-4.9.1.orig/display.h
+++ screen-4.9.1/display.h
@@ -81,7 +81,6 @@ struct display
   int   d_nonblock;            /* -1 don't block if obufmax reached */
                                /* >0: block after nonblock secs */
   char  d_termname[MAXTERMLEN + 1];    /* $TERM */
-  char *d_tentry;              /* buffer for tgetstr */
   char d_tcinited;             /* termcap inited flag */
   int  d_width, d_height;      /* width/height of the screen */
   int  d_defwidth, d_defheight;        /* default width/height of windows */
@@ -214,7 +213,6 @@ extern struct display TheDisplay;
 #define D_other                DISPLAY(d_other)
 #define D_nonblock      DISPLAY(d_nonblock)
 #define D_termname     DISPLAY(d_termname)
-#define D_tentry       DISPLAY(d_tentry)
 #define D_tcinited     DISPLAY(d_tcinited)
 #define D_width                DISPLAY(d_width)
 #define D_height       DISPLAY(d_height)
--- screen-4.9.1.orig/termcap.c
+++ screen-4.9.1/termcap.c
@@ -110,7 +110,7 @@ int he;
 {
   register char *s;
   int i;
-  char tbuf[TERMCAP_BUFSIZE], *tp;
+  char tbuf[TERMCAP_BUFSIZE < 1024 ? 1024 : TERMCAP_BUFSIZE];
   int t, xue, xse, xme;
 
   ASSERT(display);
@@ -133,16 +133,9 @@ int he;
     debug1("Extra outcap: %s\n", extra_outcap);
 #endif
 
-  if ((D_tentry = (char *)malloc(TERMCAP_BUFSIZE + (extra_incap ? 
strlen(extra_incap) + 1 : 0))) == 0)
-    {
-      Msg(0, "%s", strnomem);
-      return -1;
-    }
-
   /*
    * loop through all needed capabilities, record their values in the display
    */
-  tp = D_tentry;
   for (i = 0; i < T_N; i++)
     {
       switch(term[i].type)
@@ -154,10 +147,15 @@ int he;
          D_tcs[i].num = e_tgetnum(term[i].tcname);
          break;
        case T_STR:
-         D_tcs[i].str = e_tgetstr(term[i].tcname, &tp);
+         D_tcs[i].str = e_tgetstr(term[i].tcname, &(char *){tbuf});
          /* no empty strings, please */
          if (D_tcs[i].str && *D_tcs[i].str == 0)
            D_tcs[i].str = 0;
+    if (D_tcs[i].str && !(D_tcs[i].str = strdup(D_tcs[i].str)))
+      {
+        Msg(0, "%s", strnomem);
+        return -1;
+      }
          break;
        default:
          Panic(0, "Illegal tc type in entry #%d", i);

Attachment: signature.asc
Description: PGP signature

Reply via email to