Skip to content

tex.ch: fix hyphenation exception slot and memory leak (S941) #82

Description

@dangerzig

Summary

The \hyphenation command is intended to maintain a set of exception words, but re-hyphenating a word unconditionally increments hyph_count and displaces the old entry via Robin Hood hashing rather than replacing it in place. This wastes hash slots and leaks both the old string (from make_string) and the old token list.

The existing web2c workaround in tex.ch decrements hyph_count and flushes the duplicate string, but deliberately skips flush_list(hyph_list[h]) with the comment "it interferes with trip.log."

Proposed fix

Add flush_list(hyph_list[h]) to free the old token list, and remove the comment.

{repeat hyphenation exception; flushing old data}
flush_string; s:=hyph_word[h]; {avoid |slow_make_string|!}
flush_list(hyph_list[h]); {free old hyphen position list}
decr(hyph_count);
goto found;

Trip test impact

This reduces string pool memory by ~5 words at every Memory usage report in trip.log and trip.fot. tripin.log and trip.typ are identical.

Test file

With the default hyph_size = 307:

\newcount\n \n=0
\loop \advance\n by 1
  \hyphenation{test-ing}  % same word, 308 times
\ifnum\n<308 \repeat
\bye

On an unmodified tex.web build, this triggers "TeX capacity exceeded, sorry [exception dictionary=307]" on the 308th insertion, even though only one unique word was defined.

Context

This was reported to Professor Knuth by letter (March 2026) and to tex-k@tug.org in the thread "Three potential bugs in tex.web (Version 3.141592653)". The full changefile patch covering this and 7 overflow fixes was sent to the list for review.

The complete diff (tex-ch-overflow-patches.diff) and cover document (tex-ch-overflow-report.pdf) are attached to the companion overflow issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions