Subject | RE: [IB-Architect] dsql/dsql.c v2 A Cursor Too Far. |
---|---|
Author | Patrick J. P. Griffin |
Post date | 2000-09-09T02:27:33Z |
Chris,
My current reading of the code makes me think that a second form of the
name_length routine may be unnecessary. If fact, my suggested changes
removes the first call to name_length. The first call to name_length in this
code segment was used to set one of the two limits to the FOR statement.
(The other limit was set by the compiled length of the CURSOR variable.)
My proposed alteration to the FOR statement causes it to terminate from any
of three conditions.
1) the compiled length of the CURSOR variable.
2) finding the first NULL character.
3) finding the first SPACE character.
The early part of the GDS_DSQL_SET_CURSOR routine has two different cursor
name handling components. Dialect 3 is handled earlier in the module (in
the THEN part of the IF statement) and is not affected by my proposed
alterations. My proposed alterations only exist in the ELSE portion.
My change only affects Dialect 1 processing and simply ensures that the
first space, if it exists, is replaced by a null. With that accomplished,
the variable CURSOR contains a null terminated string just as if it was
called from C, Pascal or any other language that uses null terminated
strings. If the string was already null terminated no alterations are made.
Since Dialect 1 does not allow imbedded blanks, this change should not break
any existing Dialog 1 processing while correcting problems in any language
that, like COBOL, does not use null terminated strings.
Thanks for taking the time to consider the value and validity of my
proposal.
...pat
-----Original Message-----
From: Chris Jewell [mailto:cjewell@...]
Sent: Friday, September 08, 2000 7:30 PM
To: IB-Architect@egroups.com
Subject: Re: [IB-Architect] dsql/dsql.c v2 A Cursor Too Far.
to the story. The static function name_length() is called twice in
GDS_DSQL_SET_CURSOR(), but those calls don't really want the same
semantics.
The first call is handling a traditional, non-delimited identifier,
and therefore should stop at the first blank it finds (because blanks
are not permitted in an ordinary identifier). That is exactly what
name_length() did in 5.6.
The second call is handling something which *may* have been a
delimited identifier which had its delimiters stripped off, and
therefore is permitted to contain embedded blanks (but is sure to be
null- terminated, because the null was inserted either 2 lines or 10
lines above that second call to name_length()), and should only ignore
trailing blanks, not embedded blanks. The 6.0 version of
name_length() handles that situation just fine.
We need 2 different functions to be called from those two places,
quite apart from any questions about null-terminated strings. The
first name_length() call should instead call something, which doesn't
exist yet, but will probably look like the following UNTESTED code.
static USHORT length_before_first_blank(TEXT *name)
{
TEXT * first_blank;
first_blank = (TEXT *) strchr((char *) name, ' ');
if (first_blank)
return (USHORT) (first_blank - name);
else
return (USHORT) strlen((char *) name);
}
(The 5.6 version of name_length() would also do fine, but as an
Inprise employee I feel on safer ground suggesting a new fix than
posting a chunk of the pre-open-source code in a public place. I
don't want the rottweilers nipping at the seat of my trousers. <grin>)
Delimited identifiers are new in 6.0, which makes it unsurprising for
code related to delimited idents to turn up at the site of something
that worked for several previous releases but fails in 6.0.
That COBOL doesn't use null-terminated strings is very old news, yet
your applications work with previous releases of IB. In IB 5.X, I can
see that the name was ALWAYS passed to name_length() as in 6.0, with
no worries at all. It appears to me that the implementor of delimited
identifiers introduced the bug you are experiencing when he changed
the semantics of name_length(), and that my suggestion above should
fix it.
--
Chris Jewell developer/sysadmin voice:
831-431-6531
cjewell@... InterBase Software, Borland-Inprise fax:
831-431-6510
To unsubscribe from this group, send an email to:
IB-Architect-unsubscribe@onelist.com
My current reading of the code makes me think that a second form of the
name_length routine may be unnecessary. If fact, my suggested changes
removes the first call to name_length. The first call to name_length in this
code segment was used to set one of the two limits to the FOR statement.
(The other limit was set by the compiled length of the CURSOR variable.)
My proposed alteration to the FOR statement causes it to terminate from any
of three conditions.
1) the compiled length of the CURSOR variable.
2) finding the first NULL character.
3) finding the first SPACE character.
The early part of the GDS_DSQL_SET_CURSOR routine has two different cursor
name handling components. Dialect 3 is handled earlier in the module (in
the THEN part of the IF statement) and is not affected by my proposed
alterations. My proposed alterations only exist in the ELSE portion.
My change only affects Dialect 1 processing and simply ensures that the
first space, if it exists, is replaced by a null. With that accomplished,
the variable CURSOR contains a null terminated string just as if it was
called from C, Pascal or any other language that uses null terminated
strings. If the string was already null terminated no alterations are made.
Since Dialect 1 does not allow imbedded blanks, this change should not break
any existing Dialog 1 processing while correcting problems in any language
that, like COBOL, does not use null terminated strings.
Thanks for taking the time to consider the value and validity of my
proposal.
...pat
-----Original Message-----
From: Chris Jewell [mailto:cjewell@...]
Sent: Friday, September 08, 2000 7:30 PM
To: IB-Architect@egroups.com
Subject: Re: [IB-Architect] dsql/dsql.c v2 A Cursor Too Far.
> From: "Griffin, Patrick J." <griffin@...>...
> Date: Fri, 8 Sep 2000 15:10:16 -0400
> Meditating on the randomness of this problem I was stuck by the thought:It is, and I think you're in the right area there, but there is more
> COBOL doesn't use null terminated strings.
>
>
> Studying GDS_DSQL_SET_CURSOR I see:
>
> USHORT i;
> length = name_length (input_cursor);
> for (i=0; i<length && i< sizeof(cursor)-1; i++)
> cursor [i] = UPPER7 (input_cursor [i]);
> cursor [i] = '\0';
>
> where, I believe, name_length is expecting a null terminated string.
to the story. The static function name_length() is called twice in
GDS_DSQL_SET_CURSOR(), but those calls don't really want the same
semantics.
The first call is handling a traditional, non-delimited identifier,
and therefore should stop at the first blank it finds (because blanks
are not permitted in an ordinary identifier). That is exactly what
name_length() did in 5.6.
The second call is handling something which *may* have been a
delimited identifier which had its delimiters stripped off, and
therefore is permitted to contain embedded blanks (but is sure to be
null- terminated, because the null was inserted either 2 lines or 10
lines above that second call to name_length()), and should only ignore
trailing blanks, not embedded blanks. The 6.0 version of
name_length() handles that situation just fine.
We need 2 different functions to be called from those two places,
quite apart from any questions about null-terminated strings. The
first name_length() call should instead call something, which doesn't
exist yet, but will probably look like the following UNTESTED code.
static USHORT length_before_first_blank(TEXT *name)
{
TEXT * first_blank;
first_blank = (TEXT *) strchr((char *) name, ' ');
if (first_blank)
return (USHORT) (first_blank - name);
else
return (USHORT) strlen((char *) name);
}
(The 5.6 version of name_length() would also do fine, but as an
Inprise employee I feel on safer ground suggesting a new fix than
posting a chunk of the pre-open-source code in a public place. I
don't want the rottweilers nipping at the seat of my trousers. <grin>)
Delimited identifiers are new in 6.0, which makes it unsurprising for
code related to delimited idents to turn up at the site of something
that worked for several previous releases but fails in 6.0.
That COBOL doesn't use null-terminated strings is very old news, yet
your applications work with previous releases of IB. In IB 5.X, I can
see that the name was ALWAYS passed to name_length() as in 6.0, with
no worries at all. It appears to me that the implementor of delimited
identifiers introduced the bug you are experiencing when he changed
the semantics of name_length(), and that my suggestion above should
fix it.
--
Chris Jewell developer/sysadmin voice:
831-431-6531
cjewell@... InterBase Software, Borland-Inprise fax:
831-431-6510
To unsubscribe from this group, send an email to:
IB-Architect-unsubscribe@onelist.com