Subject: bug#8766: Bug in sha1sum?

From: Jim Meyering <[email-masked]>
Date: Tue, 31 May 2011 09:56:28 +0200

Theo Band wrote:
> On 05/31/2011 01:03 AM, Alan Curry wrote:
>> Theo Band writes:
>>> Hi
>>>
>>> I'm not sure, but I think I found a bug in sha1sum. It's easy to
>>> reproduce with any file that contains a backslash (\) in the name:
>>> echo test > test
>>> $ sha1sum test
>>> 4e1243bd22c66e76c2ba9eddc1f91394e57f9f83  test
>>> $ mv test 'test\test'
>>> $ sha1sum 'test\test'
>>> \4e1243bd22c66e76c2ba9eddc1f91394e57f9f83  test\\test
>>>
>>> I expect the file sha1sum to be the same after renaming the file (a
>>> backslash is prepended to the otherwise correct result).
>> This result violated my expectations too, but it turns out to be a documented
>> feature:
>>
>>      For each FILE, `md5sum' outputs the MD5 checksum, a flag indicating
>>   a binary or text input file, and the file name.  If FILE contains a
>>   backslash or newline, the line is started with a backslash, and each
>>   problematic character in the file name is escaped with a backslash,
>>   making the output unambiguous even in the presence of arbitrary file
>>   names.  If FILE is omitted or specified as `-', standard input is read.
>>
>> (the sha*sum utilities all refer back to md5sum's description)
>>
>> I better go fix all my scripts that rely on /^[0-9a-f]{32} /
>>
> man sha1sum, info sha1sum and sha1sum --help don't show me this info.
> Instead I read this:
>
>> The default mode is to print a line with checksum, a character
> indicating type (`*' for binary, ` ' for text), and name for each FILE.
>
> Would that mean the documentation in the coreutils-5.97-23.el5_6.4 is
> outdated? If so, is there perhaps an undocumented option that does not
> output this backslash?
> I make an index of all my files to find duplicates. The backslash
> doesn't help.

That feature is required to allow checking the hash of any file name
that contains newlines.  There is no option to disable it.
That omission in the documentation was corrected by COREUTILS-6_8-69-g826ff08.

If you're sure you have no newline-afflicted file name,
you can safely filter out the backslashes with this:

    sed 's/^\\//;s/\\\\/\\/g'

E.g.,

    $ touch a\\b
    $ md5sum a\\b | sed 's/^\\//;s/\\\\/\\/g' | md5sum -c -
    a\b: OK