Code that is almost correct is pernicious, and I often encounter
it in the course of my consulting practice. While working on a client problem the
other day, I encountered just such an example, an almost correct
use of F$LOCATE
to determine if a process holds a particular privilege or identifier. The fault is
not in F$LOCATE, it is in the way that F$LOCATE (or any other index
function) is used.
In this case, I found the error in the released version of a
major non-HP product used on OpenVMS. This same product contained both this
coding error and an interoperabilty problem with its management of the
LNM$FILE_DEV logical name (I will cover the LNM$FILE_DEV
problem in a future column).
This column will talk about the first of the two errors, the frequent
incorrect coding of the F$LOCATE lexical function. This error falls
into the species of code that often works most of the
time. As such, its failures seem unpredictable and irregular. The
consequences of the failures also seem
erratic and unpredictable. The supreme irony
is that the difference between the correct and incorrect code is
less than ten (10) characters.
Consider the following test case:
$ X = "USER_PAY"
$ Y = "REMOTE,DIALUP,KUMQUAT,USER_PAYROLL"
$ IF F$LOCATE(X, Y) .NE. F$LENGTH(Y) THEN -
WRITE SYS$OUTPUT "User has USER_PAY permission"
|
Running the above sample clearly shows something is wrong. The user does not
have the USER_PAY identifier, yet the code found it. What is the
pathology of the failure?
The pathology of the failure is the matching of a partial element,
not a complete element. The code author omitted wrapping the two strings in
delimiter characters (in this case ,). The correction consists of wrapping
the strings in delimiter characters to anchor the F$LOCATE
at beginning and end, ensuring
that if and when a match occurs, it is to a complete element.
The correct code for the preceding would be:
$ X = "USER_PAY"
$ Y = "REMOTE,DIALUP,KUMQUAT,USER_PAYROLL"
$ IF F$LOCATE(",''X',", ",''Y',") .NE. F$LENGTH(",''Y',") THEN -
WRITE SYS$OUTPUT "User has USER_PAY permission"
|
If one carefully analyzes the cases, the failures occur in at least two
different situations:
-
the searched for string is the leading component of another string which appears at
the end of the list of possibilities
-
the searched for string is a substring of another string in the list
(e.g. there is another identifier with the same ending).
Often, these problems appear in code which checks the rights or
privilege lists returned by the F$GETJPI lexical function. However, the
coding error can manifest itself in a wide range of situations,
particularly when validating inputs.
In general, this is an example of what can happen when implementation and
design are not as thorough as they can be. The size of your organization is
irrelevant; in the end analysis, code is written by humans, and will contain
errors. It is our responsibility as IT professionals to keep a watchful eye for
errors, whether they affect us immediately or in the future. Today's minor error
could be a show-stopper tomorrow.
Biography:
Robert Gezelter, CDP, Software Consultant,
guest lecturer and technical facilitator has more than 25 years of
international consulting experience in private and public sectors.
Mr. Gezelter is a regular guest speaker at technical conferences
world-wide such as HPETS (formerly DECUS).
He has worked extensively in OpenVMS since its initial release
as VAX/VMS in 1978. He has worked extensively in computer architectures,
operating systems, APIs, networks, security, and related matters.
Among his published work are articles appearing in Network World, Open
Systems Today, Digital Systems Journal, Digital News, and Hardcopy. He is
also a contributor to the Computer Security Handbook, 4th Edition, Wiley,
2002.
Mr. Gezelter can be reached via email at
gezelter@rlgsc.com.