Defect 1 - Identified by Samuel T. Harris
All of the unbounded string components suffer the same problem. In certain places, a string parameter's items pointer is dereferenced in order to assign slices to the accessed array. If the length of a string is zero, then this pointer is a null pointer. Dereferencing the null pointer raises constraint_error.
Another concern is that other aggregate components may have the same kind of problem. An exhaustive study of all the unbounded components has not been made.
One of the submitted correction proposals will be finalized and released as the official version, probably during January of 2001.
Finally, please note that the described error condition is not recognized by obsolete versions of GNAT.
Because almost all of this code has been prepared using a 3.12p version of GNAT (that does not recognize the error condition as indicated above,) some of the proposed corrections listed later have not been fully tested. This has been indicated where it applies.
Each kind of component has a test routine of the same name with "test" prefixed. Each can be link and run individually. Also included is a test_null_strings program which withs them all and runs them but at least one version of GNAT fails to link it. So also provided is a test_all.bat file which is a script which calls each individually linked test routine.
Also in the test tar file, please find test.apex.ada83.before.out, test.apex.ada95.before.out, and test.gnat.ada95.before.out to see the differences in the test output. (Also find test.gnat.ada95.after.out which shows all tests pass after the fixes proposed below are in place.)
You may be tempted to run all the tests on all the
components to see how each fails. What you will find
is that any component which used semaphores will run
into a deadlock. After a failure on nil or tmp, a subsequent
use will deadlock since the semaphore from the previous
failure was no cleared. This is because the component
catches very specific exceptions but has no fail-safe
Adding one now is not being proposed because
the only other exception to be concern with at this
time is constraint_error due to null pointer dereference,
which this fixes. The other reason for not proposing this
now is that having fail-safe exception handlers is a general
topic which affects all components which used semaphores.
This would probably make a good discussion topic in its
Correction proposal 1
The defect is easily corrected with appropriate checks against the length of the string. Some of the checks are not strictly necessary but were added for consistency among overloded subprograms and because in several of the subprograms, the checks avoid unnecessary processing and provide a kind of runtime optimization. For instance, when prepending a null string to another string, then there is really nothing that needs to be done!
Each added line begins directly on column one and are all suffixed with the comment '--# STH' for easy detection. The appropriate package bodies are included in the tar file; the package declarations do not require any changes.
The defect is easily corrected with appropriate checks for a null object (emphasizing the difference between the unbounded and bounded component forms.) Only the checks that are strictly necessary are added and they surround only the problematic code (in order to highlight that code) and are not intended to affect performance. Checking the "in" parameter is prefered over checking the "in out" one even though the checks in different subprograms are then less similar.
Each added line begins directly on column one and are all suffixed with the comment '--#' for easy detection. The appropriate package bodies are included in the tar file; the package declarations do not require any changes.