There's a bit of confusion going on here. I'll try to clear it up,
but in the future everybody please
- don't jump to premature conclusions. Stick to the observations
first. If you then want to speculate on what's going on, go ahead,
but don't omit the facts for this.
- when describing observed behaviour, *ALWAYS*, if at all possible,
include *COMPLETE* test code that shows the behaviour.
Richard D. Jackson wrote:
On Thu, 2003-02-13 at 01:27, Frank Heckenbach wrote:
<snip>
> In this case what gpc does is truncate the return value to fit into
> myStr. Other words this does not cause a compiler error so the compiler
> sees these two strings as being equivlant even though that is not the
> case.
My previous reply to Chuck's mail should have made this clear.
Did not get that one until after I wrote my reply.
Sure, and I didn't see your comment until I wrote mine -- just
wanted to avoid some confusion ...
<snip>
> What is interesting is that.
> Given
>
> var
> buff : String (255);
>
> I can stuff 30925 chars into it after that majic number I get a
> segfault.
I can't. The following stops at 255.
program Foo;
var
buff : String (255);
counter : Integer;
begin
buff := '';
counter := 1;
repeat
buff := buff + ' ';
WriteLn (Length (buff))
WriteLn ( counter );
counter := counter + 1;
until False
end.
Here even though the Length of buff will stay 255 after the 255th
iteration counter will go to 30951 before the segfault. Which means the
sting buffer is going out of bounds.
No, it isn't. Actually, the string buffer is static and doesn't go
anywhere. What you might mean is a string index going out of bounds,
but no string indexing is done, so this isn't happening, either.
What really happens is:
- The string is silently truncated. This may not always be
desirable, but is permitted by the standard (cf. my reply to
Chuck), and it's no security hole.
- A known bug, as listed in the to-do list: "possible stack overflow
when using string concatenation in a loop [...]". A stack overflow
manifests itself as a segfault on many systems, but AFAIK, it's no
security problem, either (at least on systems that have a slightly
sane memory management).
Actually, I had thought of the latter, but since you said "I can
stuff 30925 chars into it", I thought it wasn't that, so I didn't
mention it previously.
If what you mean is treating the string as an array of char and
indexing out of range, this would be a matter of range-checking(*)
-- I'm not sure if you mean this, that's why it's always a good idea
to include some example code!
Here is what I used but note it is slopy as I was trying out other
things as well. [...]
OK, that's the same issue (`Concat' and `+' for strings are
basically the same).
Prof. A Olowofoyeku (The African Chief) wrote:
Richard D. Jackson wrote:
What is interesting is that.
Given
var
buff : String (255);
I can stuff 30925 chars into it after that majic number I get a
segfault. So what is happening here? If I suround a string with
other vars they are not getting overwriten wich is a good thing but
I still wonder why it did not segfault at 256.
That is just chance. Take the same program to another PC running the
same OS (or compile for another OS) and you might well get the
segfault in a different place.
I also don't think that you can rely on other variables not being
overwritten. Something is being overwritten.
If it was really an out-of-bounds (string or array) index, as I had
conjectured, this would be true. For the stack overflow bug, AFAIK
there's no danger of overwriting something else (just a program
crash ;-).
Richard D. Jackson wrote:
I'd like to see range checking available as an option but I think the
work to integrate gpc with gcc is more important.
I agree with this as a carfull programer will not allow this to happen.
The one place where you do need range checking is input which you can
get around by using a libc function I forget the exact function names
but I know they are there in libc due to all of the buffer overflow
security issues.
Again, some confusion. Range checking on input would apply to
reading integer subranges (e.g., `var Foo: 1 .. 10; [...]
ReadLn (Foo)'). You can get around this by explicit tests
(`if (Foo < 1) or (Foo > 10) then Halt (1)'), or to avoid runtime
errors, even on non-numeric input, reading into a string, and using
`Val'.
But I don't think you mean this, but rather string capacity checking
during input. This does happen, so the dreaded string overflows in C
as in gets() are really not applicable.
Frank
--
Frank Heckenbach, frank@g-n-u.de,
http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: 51FF C1F0 1A77 C6C2 4482 4DDC 117A 9773 7F88 1707