Page 1 of 1

Apostrophe at beginning of file name

Posted: 18 Feb 2021 19:31
by Squashman
I was helping a user on StackOverFlow who was having a problems with apostrophes in their file names. It made wonder what happens with a file name that starts with an apostrophe.

Here I used USEBACKQ but didn't use double quotes around the file name.

Code: Select all

C:\BatchFiles\apostrophe>for /F "usebackq delims=" %G IN ('myfile.txt) do echo %G

C:\BatchFiles\apostrophe>echo LINE'1
LINE'1
The system cannot find the file ⨛✀谀潃卭数㵣㩃睜湩潤獷獜獹整㍭尲浣⹤硥e.
Then decided to take out the USEBACKQ

Code: Select all

C:\BatchFiles\apostrophe>for /F "delims=" %G IN ('myfile.txt) do echo %G

C:\BatchFiles\apostrophe>echo LINE'1
LINE'1
The system cannot find the file ⨑─阀.
Obviously we know everything should work if we double quote and use USEBACKQ

Code: Select all

C:\BatchFiles\apostrophe>for /F "usebackq delims=" %G IN ("'myfile.txt") do echo %G

C:\BatchFiles\apostrophe>echo LINE'1
LINE'1
Here I ran the SAME command back to back and the error message came out a bit different.

Code: Select all

C:\BatchFiles\apostrophe>for /F "usebackq delims=" %G IN ('myfile.txt) do echo %G

C:\BatchFiles\apostrophe>echo LINE'1
LINE'1
The system cannot find the file ⨏⌀鐀单剅剐䙏䱉㵅㩃啜敳獲杜汣晪0.

C:\BatchFiles\apostrophe>for /F "usebackq delims=" %G IN ('myfile.txt) do echo %G

C:\BatchFiles\apostrophe>echo LINE'1
LINE'1
The system cannot find the file ⨔☀耀.

C:\BatchFiles\apostrophe>echo %errorlevel%
0
Honestly I don't know what is going on here because it is reading the file and outputs the file but still throws an error.

Re: Apostrophe at beginning of file name

Posted: 18 Feb 2021 22:52
by dbenham
Looks suspiciously like the symptoms of the FOR /F bug on XP when there are unescaped/unquoted token delimiters - FOR /F is mucking about with memory that it shouldn't (uninitialized pointer, or buffer overrun, or ...? )
viewtopic.php?t=1972

I doubt you are using XP, and there are no token delimiters. But it looks like you have discovered a new way to expose the old bug.

I get the bug if the file name is exactly 11 characters long. It works fine without error with lengths 10 and 12.


This reminds me of one of the first C programs I ever wrote. It was a civil engineering application that computed the area of a trapezoid as part of measuring cut and fill for roadway design. It used a file as input, and worked perfectly as long as the file name was anything but 5 characters long. But it crashed and burned every time with a name length 5.

For a number of months we told customers to avoid file names with that length. Eventually I found I had an uninitialized pointer to a float. The routine used the pointer in a computation that was in a loop. The pointer was set toward the end of the loop, after the first computation involving that pointer. But the computation in the first iteration was thrown away, so it didn't matter what value was stored there. Most of the time everything was fine - it did the computation with the value at the "random" location, and then threw it away. But if the file name was 5 characters, the memory location had a NAN value, and the routine crashed with an exception. :twisted: That was a good lesson for a young programmer.


Dave Benham

Re: Apostrophe at beginning of file name

Posted: 19 Feb 2021 01:46
by jeb
Hi,

the error occurs after the file was read, because the FOR loop tries to read the next file!

Code: Select all

@echo off
echo this is myfile>myfile.txt
echo this is myapo> "'myapo.txt"
echo this is myapo1> "'myapo1.txt"
for /F "usebackq delims=" %%G IN ("'myapo.txt" "myfile.txt" ) do echo #1 %%G
for /F "usebackq delims=" %%G IN ('myapo.txt "myfile.txt" ) do echo #2 %%G
for /F "usebackq delims=" %%G IN ('myapo.txt) do echo #3 %%G
for /F "usebackq delims=" %%G IN ('myapo1.txt') do echo #4 %%G
for /F "usebackq delims=" %%G IN ('myapo1.txt) do echo #5 %%G

Code: Select all

#1 this is myapo
#1 this is myfile
The system cannot find the file 'myapo.txt "myfile.txt".
#3 this is myapo
#4 myapo1.txt
#5 this is myapo1
The system cannot find the file Ⱏ㞵฀耀\??\C:\Temp\t7.COM.
The leading apostrophe works like a "strong" quote, it can't be stopped by any character, probably it's stops by a 0x00 at the end of the buffer.
But then after reading the file, it tries to read the "next" filename and fails, but only if the length of the filename is exactly 11 (like Dave said), I can't even imagine why that happens.

And see the difference between test #4 and #5
Test #4 shows the filename, but #5 reads the content, a closing apostrophe changed the type of the FOR-loop.
But it's still broken, if you add a second filename after the closing apostrophe, the complete text is used as a filename.

jeb

Re: Apostrophe at beginning of file name

Posted: 19 Feb 2021 02:04
by ShadowThief
jeb wrote:
19 Feb 2021 01:46
But then after reading the file, it tries to read the "next" filename and fails, but only if the length of the filename is exactly 11 (like Dave said), I can't even imagine why that happens.
Some weird 8.3 filename processing, maybe?

Re: Apostrophe at beginning of file name

Posted: 19 Feb 2021 05:51
by penpen
I just tested, if those characters are displayed using the wrong encoding:

Code: Select all

UTF-16LE: ⨛✀谀潃卭数㵣㩃睜湩潤獷獜獹整㍭尲浣⹤硥e
Hex     : 6A E2 1B 2A 00 27 00 8C 43 6F 6D 53 70 65 63 3D 43 3A 5C 77 69 6E 64 6F 77 73 5C 73 79 73 74 65 6D 33 32 5C 63 6D 64 2E 65 78 65 00
CP 850  : jâ.*.'.ŒComSpec=C:\windows\system32\cmd.exe

UTF-16LE: ⨑─阀
Hex     : 60 E2 11 2A 00 25 00 96
CP 850  : `â.*.%.–

UTF-16LE: ⨏⌀鐀单剅剐䙏䱉㵅㩃啜敳獲杜汣晪0
Hex     : 66 E2 0F 2A 00 23 00 94 55 53 45 52 50 52 4F 46 49 4C 45 3D 43 3A 5C 55 73 65 72 73 5C 67 63 6C 6A 66 30 00
CP 850  : fâ.*.#.”USERPROFILE=C:\Users\gcljf0.

UTF-16LE: ⨔☀耀
Hex     : 6F E2 14 2A 00 26 00 80
CP 850  : oâ.*.&.€
penpen

Re: Apostrophe at beginning of file name

Posted: 19 Feb 2021 08:16
by Squashman
LOL, now everyone knows my user name on my computer.

Re: Apostrophe at beginning of file name

Posted: 22 Feb 2021 09:10
by jfl
A few more observations:

1) The problem is not related to the use of the usebackq option.
Even without it, I get the very same error for 11-bytes file names:

Code: Select all

C:\JFL\SRC\Batch\dostips>for /f "delims=" %G IN ('myfile.txt) do @echo %G
'myfile.txt line 1
The system cannot find the file 쾻뭂ᨀ耀∟.

C:\JFL\SRC\Batch\dostips>for /f "delims=" %G IN ('myfile2.txt) do @echo %G
'myfile2.txt line 1

C:\JFL\SRC\Batch\dostips>for /f "delims=" %G IN ('myfil.txt) do @echo %G
'myfil.txt line 1

C:\JFL\SRC\Batch\dostips>
2) You can also work around the bug my inserting NUL ahead of the list:

Code: Select all

C:\JFL\SRC\Batch\dostips>for /F "delims=" %G IN ('myfile.txt) do @echo %G
'myfile.txt line 1
The system cannot find the file 칏뭎Ḁ耀.

C:\JFL\SRC\Batch\dostips>for /F "delims=" %G IN ('myfile.txt NUL) do @echo %G
The system cannot find the file 'myfile.txt NUL.

C:\JFL\SRC\Batch\dostips>for /F "delims=" %G IN (NUL 'myfile.txt NUL) do @echo %G
'myfile.txt line 1

C:\JFL\SRC\Batch\dostips>
3) On my laptop, when decoding the garbage name, byte 3 is always '\xBB', and byte 6 is always '\x00'.
This differs from Squashman's system, where byte 6 was also \x00, but byte 3 was '\x2A'.

4) I never got garbage names that decoded to environment variables definitions, like on Squashman's system.
But I once got a name that included a readable string:

Code: Select all

The system cannot find the file 츛뮢㨀耀Immersive Shell.
And I really wonder where this mysterious Immersive Shell is :o . It's definitely not in the %COMSPEC% strings.