On Mon, Apr 20, 2026 at 01:21:35AM +0400, LogicLuminary wrote: > Hello again, > > I have an update. > I just built GNU Texinfo 7.3 (the latest upstream release) from source and > tested it in the same environment. > > The crash is still present in version 7.3. On this version, the error > manifests as: > malloc(): invalid size (unsorted) IOT instruction (core dumped) > > Best regards, > Leenear
I've attempted to fix this in commit 1990bf2ea7b8 (2026-05-06). The problem was due to converting newline (one byte) to two spaces (two bytes) when it occured after a period point, without any extra memory being allocated therefor. This problem appears to have been present since this part of the code was first introduced, but would be quite unlikely to occur in practice, as the code was somewhat sloppy about the amount of memory allocated and would usually have enough for the extra bytes, except in extreme cases such as the one you came up with. I fixed this by limiting the number of times the newline could be expanded to two spaces. This should be okay as the menu entry description is not expected to span many lines. (In fact, it is usually on one line, occasionally on two lines, very rarely on three lines, and practically never on more than three lines. I've allowed up to 11 lines.) Unrelated to the report, but in subsequent commits I've eliminated the use of the strcat and strncat functions from install-info.c, which was a somewhat "janky" aspect of the code which occasionally led to reports of e.g. compiler warnings. diff --git a/ChangeLog b/ChangeLog index 922e705a7f..165085bd94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2026-05-06 Gavin Smith <[email protected]> + + * install-info/install-info.c (split_entry): + Only convert "\n" to " " a limited number of times, and allocate + enough memory to do so. + + Memory overflow reported by LogicLuminary <[email protected]>. + 2026-05-06 Patrice Dumas <[email protected]> * doc/texi2any_api.texi (Texinfo Tree Conversion Functions), diff --git a/install-info/install-info.c b/install-info/install-info.c index 2fa2ecca99..0c5aac1000 100644 --- a/install-info/install-info.c +++ b/install-info/install-info.c @@ -1625,7 +1625,8 @@ split_entry (const char *entry, char **name, size_t *name_len, strncat (*name, entry, *name_len); ptr++; - *description = xmalloc (strlen (entry)); + int extra = 10; + *description = xmalloc (strlen (ptr) + extra + 1); (*description)[0] = '\0'; while (ptr[0] != '\0') @@ -1649,9 +1650,11 @@ split_entry (const char *entry, char **name, size_t *name_len, /* First of all, we eat the newline here. But then what? Sometimes the newline separates 2 sentences, so we end up with the next word starting directly after the period, - instead of after the customary 2 spaces in english. + instead of after the customary 2 spaces in English. If the previous character was a `.', then we should add 2 spaces if there is anything on the next line. + (We can only do this a limited number of times as each time + we consume an extra byte.) if it's a comma, then we should put one space. If it's neither, we just put a space. If it's some other whitespace, we shouldn't do anything. */ @@ -1661,7 +1664,10 @@ split_entry (const char *entry, char **name, size_t *name_len, endptr--; /* *ENDPTR is the 2nd last character */ if (*endptr == '.') - strcat (*description, " "); + { + strcat (*description, + extra ? (extra--, " ") : " "); + } else if (!isspace ((unsigned char) *endptr)) strcat (*description, " "); }
