bat: files of infinite length cause bat to crash

bat /dev/zero
memory allocation of 34359738368 bytes failed

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 2
  • Comments: 19 (6 by maintainers)

Commits related to this issue

Most upvoted comments

if you choose to go the hard coding route, would it be possible to use std::os::unix::fs::MetadataExt.rdev to get the device number and check if it’s 1:5 instead?

That should be reliable (https://www.kernel.org/doc/html/latest/admin-guide/devices.html), but this is a very specialized solution. There are other such files, /dev/random (1:8), /dev/urandom (1:9), or any symbolic link to one of these.

To my understanding, the title of this issue and the author’s initial comment just point out a very extreme case of the actual problem. In fact, you don’t need an infinite file to let bat run out of memory, it’s enough to use a regular file that is bigger than the available memory. Therefore, this problem is not limited to Linux and not to just a handful of special files. That’s why I think this issue should be tackled with a more general and platform independent solution.

A different idea could be the following: When the length of a line exceeds a certain limit, all it’s content gets discarded, but reading continues until the end of line. On the next line, reading continues as usual. The line being too long could be replaced by a short note.

Imagine line 52 being too long to read:

 51   │ ...
 52 ! │ <line too long>
 53   │ ...

(the ‘!’ would have the purpose of making clear that <line too long> is not actual content)

Pros:

  • following lines that are reasonably long can be displayed anyway
  • the user is told exactly which lines are too long

Cons:

  • when reading an infinite line, bat will still hang forever

To not make bat hang forever, a second limit could be added. When that one is reached, bat would abort immediately.

What is your opinion on that approach?

I’d like to point out in case it has not yet been realized, this also affect when bat is piped into another program (ie bat /dev/zero | tr '\0' '0'). This is not the effect that the standard cat has when reading a file, breaking the drop-in replaceability of cat.

“”" Whenever the output of bat goes to a non-interactive terminal, i.e. when the output is piped into another process or into a file, bat will act as a drop-in replacement for cat(1) and fall back to printing the plain file contents. “”"