home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
zcpr33
/
z33fix.0z1
/
Z33FIX.001
Wrap
Text File
|
1987-06-10
|
4KB
|
92 lines
ZCPR33 BUG FIX
==============
Fix Number: 001
Date: June 6, 1987
Resetting of the External Program Bit in the Command Status Flag
The Problem
-----------
In the process of writing Programming Note #001, I realized that there
is a weakness in the way the command processor handles the external program
flag bit in the command status flag (CSF). The command processor resets the
bit only after the command line buffer has become empty. Otherwise, it
relies on error handlers to reset the bit. New error handlers like Z33ERROR
could be expected do this, but old error handlers, which do not know about
this bit in the CSF, certainly cannot be expected to reset it. Also,
programs that set this bit before calling the parsing code in the command
processor must remember to reset the bit before returning control to the
command processor. This situation leaves the command processor
unnecessarily at the mercy of application programs.
The shell bit in the CSF has the same problem, and shell programs must
reset that bit (they generally reset the CSF to zero). However, in the case
of shells there is no way to avoid this situation. As we shall see below, a
single line of code in the command processor can deal with the problem of
the external program bit.
The Result
----------
When the external program bit is left set and the next command line is
processed, the parsing code will deal with incorrect passwords in a
different way than when the bit is not set. When the bit is not set, entry
of an incorrect password causes the command processor to vector immediately
to the error handler. If the bit is set, the error handler is not invoked;
only the bad directory flag in the file control block is set. Programs that
do not check the bad directory flag will simply act as though the referenced
directory were the currently logged directory (i.e., just the way ZCPR30
acted). Thus, the consequences of this bug are not at all serious.
Moreover, the situation will rarely arise. Here is an example command line,
the one I used to verify the problem and the fix:
A0:BASE>SAVE XX YY;WHL;XD PVT:;WHL SYSTEM
The SAVE command that runs here is the transient SAVE.COM. When it detects
the invalid numerical expression in the first token ('XX'), it sets the
error bit, the ECP bit, and the external program bit, and returns to the
command processor. The command processor invokes the error handler. If we
tell the error handler to skip the save command and go on to the rest of the
command line, the WHL command turns off the wheel byte (so that password
checking will be turned on), and then the directory of a password-protected
directory is requested. Since the external program bit is still set from
the SAVE command, if the wrong password is now entered, instead of invoking
the error handler, the command processor will run XD, which will display the
directory of A0 (not PVT). Then last next command will set the wheel byte
again.
The Fix
-------
The fix is very simple. Just before the label NEXTCMD1, which is the
entry point for processing the error handling command line, we add one extra
instruction to the preceding code:
res 3,(hl) ; Reset the external program bit
The code thus reads as follows:
ld hl,cmdstatfl ; Point to the command status flag
ld a,(hl) ; Get a copy into register A
res 1,(hl) ; Reset the actual error bit
res 2,(hl) ; Reset the actual ECP bit
and 110b ; Select ECP and error bits in original flag
cp 110b ; Test for an ECP error
jp z,error ; Process ECP error with error handler
res 3,(hl) ; Reset the external program bit
nextcmd1:
ld sp,stack ; Reset stack
It is important that the external program bit not be reset before the branch
to the error handler, since the error processing code will use the
information in this bit. Similarly, it is important that it not be reset
after NEXTCMD1, since the information in the bit will be used by the error
handler, which is invoked at the NEXTCMD1 entry point in the code.