#785497 less: with -R, escape sequences are not sent to the terminal in an atomic way, yielding a race condition

Package:
less
Source:
less
Description:
pager program similar to more
Submitter:
Vincent Lefevre
Date:
2024-05-01 04:09:07 UTC
Severity:
minor
Tags:
#785497#5
Date:
2015-05-17 01:07:17 UTC
From:
To:
The end of some lines is sometimes not colored as it should be.
I can reproduce the problem with:

  tdiff /dev/null <(seq 80) | mless -R

under zsh in an xterm, where tdiff and mless are attached, and no
*LESS* environment variables are defined. I sometimes need to do this
several dozens of time to make the problem appear on this example.

See the attached less-color.png screenshot of the xterm window:
the 51 is in white instead of green. If I type Ctrl-L, the color
is corrected, i.e. this means that the problem is not in the output,
but the way less interpreted it.

On this example, the problem always occurs for 51, when it occurs.

Since the problem doesn't always occur, I suppose that depending on
the context, the chunks received by less differ from one execution
to the other, and for some sequences of chunks, less does something
wrong.

I've also attached a file "out", which is the output of the tdiff
command above. I could also reproduce the problem with:

  cat out | mless -R

but only once.

On other (more complex) examples, the problem occurs very often.
Sometimes a part of the escape sequence appears, e.g. [32m+ at the
beginning of a line (the + is for the unified diff format).
I could never reproduce it under strace.

#785497#10
Date:
2016-01-09 20:48:15 UTC
From:
To:
I can no longer reproduce the problem with the given testcase, even
with less 458 (I suspect something else has changed in the libraries
or in the environment because it is very sensitive to timings). I can
still reproduce it quite often on some machine with a more complex
command, but not on different machines via ssh. The output has long
text lines of a diff.

#785497#17
Date:
2017-07-18 10:09:03 UTC
From:
To:
This bug was still occurring in Debian/unstable in the last few
months, but it seems that I can no longer reproduce it. However,
this is difficult to say, as it is very random.

#785497#22
Date:
2017-07-20 11:18:34 UTC
From:
To:
with libc6 2.24-12 and libtinfo5 6.0+20170715-2 (up-to-date
Debian/unstable), in case this matters.

I've just been able to reproduce it several times on a PDF file
that was added (the file being converted to text for the diff):

[...]
+Two-output division (10.5.5)
+mulRevToPair
[32m+Boolean functions of intervals (10.5.10)
+less
+precedes
[...]

The "[32m" shouldn't be there, and the color of this line is
incorrect as a consequence (the escape sequence was not interpreted
as such). On 10 tests, the problem occurred 7 times.
If I need to reproduce it:

1. Full-size xterm (274x84). This is important here.
2. scd -c 100267 | m
3. [End] to show the end of the diff.

Unfortunately, the PDF file is not public.

#785497#29
Date:
2017-07-20 12:17:17 UTC
From:
To:
Control: retitle -1 less: with -R, escape sequences are not sent to the terminal in an atomic way, yielding a race condition
logging, I could see that at about the same time this line was sent to
the terminal, an escape sequence was also sent to update the title of
the terminal, and there was a clash between the two escape sequences.

The update of the title of the terminal is done by my shell settings
via a TRAPCHLD(). More precisely, when running "scd ... | m", I get:

  │   └─> 1594  zsh
  │     ├─> 19375  zsh
  │     │ └─> 19378  perl tdiff
  │     └─> 19376  less

and when I type [End] in "less", tdiff terminates (it was blocking
due to a full output buffer, I assume), and I get:

  │   └─> 1594  zsh
  │     └─> 19376  less

The termination of process 19375 yields a SIGCHLD, trapped by the
interactive shell (1594), which updates the title of the terminal.

In the xterm logs, I can see:
1. ESC from "less";
2. the escape sequence from zsh (to update the title of the terminal);
3. the end of the escape sequence from "less": "[32m".

So, it seems that the issue is that "less" with the -R option does not
send the escape sequence in an atomic way.