Call and goto may fail when the batch file has Unix line endings

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Call and goto may fail when the batch file has Unix line endings

#16 Post by dbenham » 12 Feb 2019 21:42

dbenham wrote:
11 Feb 2019 09:17
I don't have time to do further investigation now, but I hope that these discoveries may help resolve one or both of these unexplained edge cases:
That was wishful thinking. I couldn't remember any details other than at least one of those issues involved CALL. But I looked, and the label scanner is totally unrelated to either of those issues :(


Dave Benham

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Call and goto may fail when the batch file has Unix line endings

#17 Post by dbenham » 12 Feb 2019 22:57

So here is my current understanding of the label scanner process:

1) The label scanner attempts to read one line at a time, but it is limited to a 512 byte buffer, and it only recognizes \r\n as end-of-line. So when it reads a "line" of data, it reads through the first encountered \r\n, or end-of-file, or 512 bytes, whichever comes first.

2) Once read, the scanner looks within the current buffer contents for the label. While scanning the buffer, it recognizes \n as the end of a logical line, so it can properly find most labels when the file is in unix format. But if the label happens to have been split at the 512 byte boundary, then the label is missed.

3) Once the label is found, the batch scanner must position the batch file pointer to the end of the label line. It continues to scan the buffer and places the file pointer to the position after the first \n that it encounters after the label. If \n is not found, then the batch file pointer is put at the end of the buffer position. I don't know whether the file pointer is actually moved, or if it remains where it is, and the leftover buffer is prepended to whatever the normal command reader reads next.

I believe the above rules account for all of the examples in this thread.

One other result of this design is it would limit the maximum label length to 512 bytes. But cmd actually limits labels to length 128 bytes. Any characters after that are simply ignored in both the CALL line and the :label line. However, as demonstrated by jeb, if the label line exceeds 512 bytes, then those extra characters are treated as the next command to execute.

Code: Select all

@echo off

call :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 125
call :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 126
call :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 127
call :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 128
call :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 129
call :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 130
exit /b

:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo %1 finds 125
exit /b
:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo %1 finds 126
exit /b
:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo %1 finds 127
exit /b
:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo %1 finds 128
exit /b
:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo %1 finds 129
exit /b
:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
echo %1 finds 130
exit /b
--OUTPUT--

Code: Select all

125 finds 125
126 finds 126
127 finds 127
128 finds 128
129 finds 128
130 finds 128

Dave Benham

Post Reply