On Sun, Nov 21, 2021 at 01:40:13AM +1100, Brendan O'Dea wrote: > Malformed info files cause install-info to produce corrupted dir files. > > See attached example, where the folding info page contains: > > START-INFO-DIR-ENTRY > * folding: folding editor minor mode for Emacs > END-INFO-DIR-ENTRY > > which results in the corrupted `dir` file in the attached archive. > > I'm submitting a patch to the folding author to fix the @direntry for that > package, but install-info should probably be more resilient to badly formed > input. > > Some poking around suggests that the problem is in reformat_new_entries, > where this sequence near the top of the for loop: > > split_entry (entry->text, &name, &name_len, &desc, &desc_len); > free (entry->text); > > frees entry->text. When format_entry is called at the bottom that loop, it > exits early due to this condition (desc is NULL): > > if (!desc || !name) > return 1; > > ...which does not set outstr_out (entry->text), leading to the corruption. > > --bod
Thanks for tracking it down to this. I'm not very familiar with the code for install-info at all so it is slow for me to fix. (I'm not familiar with all the options for install-info either.) The best I've been able to come up with at the moment is the following: diff --git a/install-info/install-info.c b/install-info/install-info.c index e10f492261..32868acbf5 100644 --- a/install-info/install-info.c +++ b/install-info/install-info.c @@ -1542,6 +1542,7 @@ format_entry (char *name, size_t name_len, char *desc, size_t desc_len, if (offset_out) strncat (outstr, line_out, offset_out); + free (*outstr_out); *outstr_out = outstr; *outstr_len = strlen (outstr); return 1; @@ -1657,7 +1658,6 @@ reformat_new_entries (struct spec_entry *entries, int calign_cli, int align_cli, char *name = NULL, *desc = NULL; size_t name_len = 0, desc_len = 0; split_entry (entry->text, &name, &name_len, &desc, &desc_len); - free (entry->text); /* Specify sane defaults if we need to */ if (calign_cli == -1 || align_cli == -1) This works okay (tested). Do you think it is all right? I'll commit this code soon if nobody has any other ideas. I couldn't see an easy way in reformat_new_entries to remove the faulty entry. I'd prefer to fix this in the simplest, least intrusive way possible so as not to risk breaking something. I had tried adding error code to set the line to an empty string if format_entry was going to exit early, but this led to problems later on in the code (in menu_line_equal) which didn't work for empty strings. This meant that existing (correct) lines in the dir file would be deleted due to menu_line_equal incorrectly returning true. Rather than try to fix this, just pass through the original line unaltered. With your test this leads to the final output: --- File: dir, Node: Top This is the top of the INFO tree This (the Directory node) gives a menu of major topics. Typing "q" exits, "H" lists all Info commands, "d" returns here, "h" gives a primer for first-timers, "mEmacs<Return>" visits the Emacs manual, etc. In Emacs, you can click mouse button 2 on a menu item or cross reference to select it. * Menu: Emacs * Emacs FAQ: (efaq). Frequently Asked Questions about Emacs. * folding: folding editor minor mode for Emacs --- and I have checked this is idempotent for the input files you sent (running install-info more than once on the same file doesn't make any more changes).