[luatex] 'Out by one' error (?) in \csname messages

luigi scarso luigi.scarso at gmail.com
Mon Jun 9 10:57:03 CEST 2014


On Mon, Jun 9, 2014 at 1:36 AM, Akira Kakuto <kakuto at fuk.kindai.ac.jp>
wrote:

> With the TL2014 pretest version of LuaTeX,
>>
>>     \csname\csname\endcsname
>>
>> leads to the error
>>
>>     ! Missing \endcsname inserted.
>>     <to be read again>
>>     \^^@csnam\^^@endcsnam
>>     l.1 \csname\csname\endcsname
>>
>> which looks like some form of 'out by one' issue.
>>
>
> I think that is related to the following, since
> it is already fixed in the LuaTeX trunk.
>
> %
> % s.tex
> %
> \def\use#1{#1}
> \use\fXabc
> \bye
>
> (./s.tex
> ! Undefined control sequence.
> <argument> \fXabc       \use #1X-#1
>           l.2 \use\fXabc
>
> Best,
> Akira
>
>
>
The problem is here in tex/printing.w

luatex calls tprint_esc("csname")

   573 void tprint_esc(const char *s)
    574 {                               /* prints escape character, then
|s| */
    575     int c;                      /* the escape character code */
    576     /* Set variable |c| to the current escape character */
    577     c = int_par(escape_char_code);
    578     if (c >= 0 && c < STRING_OFFSET)
    579         print(c);
    580     tprint(s);
    581 }


At line 579 the '\' is stored into  the global trick_buf[0],
and tally is incremented, so that trick_buf[tally] is the location of the
next char to be saved
Then luatex calls tprint("csname")


    323 @ |char *| versions of the same procedures. |tprint| is
    324 different because it uses buffering, which works well because
    325 most of the output actually comes through |tprint|.
    326
    327 @c
    328 void tprint(const char *sss)
    329 {
    330     char *buffer = NULL;
    331     int i = 0; /* buffer index */
    332     int newlinechar = int_par(new_line_char_code);
    333     int dolog = 0;
    334     int doterm = 0;
    335     switch (selector) {
    336     case new_string:
    337         append_string((const unsigned char *)sss, (unsigned)
strlen(sss));
    338         return;
    339         break;
    340     case pseudo:
    341         while (*sss) {
    342            if (tally++ < trick_count) {
    343                trick_buf[tally % error_line] = (packed_ASCII_code)
*sss++;
    344            } else {
    345                return;
    346            }
    347         }

At line 342 the if statement increments tally again, so the first time  the
'c' of "csname"
is saved in (assuming error_line=79 as usual)
trick_buf[tally % error_line] = trick_buf[2] .
The  content of trick_buf[1] depends on the format.
The while loop at line 341 stops when it sees '\0' of csname , so this is
the reason why we don't see the final character.

-- 
luigi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://tug.org/pipermail/luatex/attachments/20140609/f6bab0b3/attachment.html>


More information about the luatex mailing list