Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is '<<<' filtering null bytes in gdb where '<()' does not?

I recently discovered that the <<< trick in gdb to feed the stdin of the debugged program is filtering the null bytes out from the stream.

Here is a small example (that anybody should be able to reproduce at home) to testify that it filters out the null bytes:

$> python -c 'print("A\x00" * 10)' | cat -A
A^@A^@A^@A^@A^@A^@A^@A^@A^@A^@$
$> gdb /bin/cat

... gdb license prelude ... snip...

(gdb) r -A <<< $(python -c 'print("A\x00" * 10)')
Starting program: /bin/cat -A <<< $(python -c 'print("A\x00" * 10)')
/bin/bash: warning: command substitution: ignored null byte in input
AAAAAAAAAA$
[Inferior 1 (process 3798) exited normally]

Where, using the bash-specific <() process substitution leave the null bytes reach the program stdin within gdb:

(gdb) r -A < <(python -c 'print("A\x00" * 10)')
Starting program: /bin/cat -A < <(python -c 'print("A\x00" * 10)')
A^@A^@A^@A^@A^@A^@A^@A^@A^@A^@$
[Inferior 1 (process 3804) exited normally]

So, I have always thought that <<< and <() were doing about the same thing which is now obviously wrong. I would like to know what are the differences between the two methods and have an explanation about the bash mysterious error message stating that:

/bin/bash: warning: command substitution: ignored null byte in input

Any help is more than welcome!

like image 287
perror Avatar asked Mar 22 '17 14:03

perror


People also ask

How to check if a value is null in Das?

Suspect you have outer joins. Checking for = or != in the where kills the outer. See solution from das. Since, by definition NULL is an unknown value (bit simplified but OK for this explanation), it will neither equal or not equal a given value - that's why the IS NULL is required here.

How do I select null values in a chart?

You cannot select null values in charts, so if you want to somehow be able to select those values, you can create a flag field so if the field "Column B" is empty, blank or has a null (i.e.: when the length of the field is zero) it will add a "1" to the NullFlag field, otherwise, it will add a "0".

What is null in T-SQL?

This quote is taken from 70-461 training kit. "T-SQL—again, based on standard SQL—implements only one general purpose mark called NULL for any kind of missing value. This leads to three-valued predicate logic."


1 Answers

So, I always though that <<< and <() were doing about the same thing which is now obviously wrong.

Those don't do at all the same thing. The <<< operator redirects a "here string" to the associated process's standard input. Process substitution via <() expands to the name of a file (generally a FIFO or similar) from which the standard output of the given command can be read.

What you seem to mean is that the combination of <<< with command substitution (via $() or backticks) does about the same thing as the combination of ordinary standard input redirection via < with process substitution. This is true, but as you've discovered, the semantics are not exactly equivalent.

I would like to know what are the differences between the two methods and have an explanation about the bash mysterious error message

The key difference is that redirecting from a here string requires first producing the string as a value held by the shell (which you're doing via a command substitution), whereas redirecting a process substitution involves the redirected output being read directly by the associated process.

Ultimately, the diagnostic you receive indicates that the unexpected behavior you experienced arises from the behavior of command substitution, not the behavior of <<<. Although I don't find it explicitly documented, I am not at all surprised that Bash strips null characters from program output when it processes a command substitution, for I expect its internal representation of shell strings to be as C strings. C strings are null-terminated, and therefore cannot represent character sequences that include the null character.

Update:

Note also that, as @sorontar observed in comments on the other answer, POSIX says that if the output of the command in a command substitution contains null bytes then the result is unspecified. Bash is thus free to strip the null bytes -- or indeed to do more or less anything it wants when it sees them -- without sacrificing POSIX conformance. Other shells may make different choices in this regard than Bash does. This is an excellent reason to avoid command substitutions where a null byte appearing in the command's output is a foreseeable possibility.

like image 150
John Bollinger Avatar answered Sep 25 '22 16:09

John Bollinger