Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2005-12

StrPos giving a access violation

17 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

The 3rd unit test fails due to StrPos giving a access violation. I ran this same unit test under Delphi 7 and it passed as StrPos returned a nil value when passing two '' param values.

Has this been reported as a bug yet?

-----------------  CUT  -------------------
var
   lFrom: string;
   lSearch: string;
   lResult: PChar;
begin
   lFrom   := 'abc';
   lSearch := 'b';
   lResult := StrPos(Pointer(lFrom), Pointer(lSearch));
   AssertEquals('Failing on 1', 'bc', string(lResult));
   lSearch := 'x';
   lResult := StrPos(Pointer(lFrom), Pointer(lSearch));
   AssertEquals('Failing on 2', '', string(lResult));
   lFrom   := '';
   lSearch := '';
   lResult := StrPos(Pointer(lFrom), Pointer(lSearch));
   AssertEquals('Failing on 3', '', string(lResult));

----------------- END -------------------

Regards,
- Graeme -

Reply by email

Graeme Geldenhuys

Hi

Forgot to mention, I ran this using:
Free Pascal Compiler version 2.0.1 [2005/10/02] for i386 on Windows 2000

G.

Earlier message 41 lines
-------- Original Message -------- Subject: StrPos giving a access violation Date: Thu, 08 Dec 2005 14:26:14 +0200 From: Graeme Geldenhuys Organization: Master Maths (Pty) Ltd To: FPC developers' list Hi, The 3rd unit test fails due to StrPos giving a access violation. I ran this same unit test under Delphi 7 and it passed as StrPos returned a nil value when passing two '' param values. Has this been reported as a bug yet? ----------------- CUT ------------------- var lFrom: string; lSearch: string; lResult: PChar; begin lFrom := 'abc'; lSearch := 'b'; lResult := StrPos(Pointer(lFrom), Pointer(lSearch)); AssertEquals('Failing on 1', 'bc', string(lResult)); lSearch := 'x'; lResult := StrPos(Pointer(lFrom), Pointer(lSearch)); AssertEquals('Failing on 2', '', string(lResult)); lFrom := ''; lSearch := ''; lResult := StrPos(Pointer(lFrom), Pointer(lSearch)); AssertEquals('Failing on 3', '', string(lResult)); ----------------- END ------------------- Regards, - Graeme -

Reply by email

Graeme Geldenhuys
to Graeme Geldenhuys

Hi,

I put a breakpoint inside StrPos and stepped through the code. It raised a "External SIGSERV" error on the second line:

   p:=strscan(str1,str2^);

I don't understand assembler so couldn't debug into StrScan.

Regards,
- Graeme -

Graeme Geldenhuys wrote
lFrom := ''; lSearch := ''; lResult := StrPos(Pointer(lFrom), Pointer(lSearch)); AssertEquals('Failing on 3', '', string(lResult));

Reply by email

Jonas Maebe
to Graeme Geldenhuys: The 3rd unit test fails due to StrPos giving a access violation. I ran this same unit…
Graeme Geldenhuys wrote 5 lines
The 3rd unit test fails due to StrPos giving a access violation. I ran this same unit test under Delphi 7 and it passed as StrPos returned a nil value when passing two '' param values. Has this been reported as a bug yet?

No. I've fixed it and added a test. You can check whether something has been reported as a bug by going to
http://www.freepascal.org/bugs.html

If possible, a copy of your unit tests would be nice addition to our test suite.

Jonas

Reply by email

Marc Weustink
to Graeme Geldenhuys: The 3rd unit test fails due to StrPos giving a access violation. I ran this same unit…
Graeme Geldenhuys wrote 18 lines
Hi, The 3rd unit test fails due to StrPos giving a access violation. I ran this same unit test under Delphi 7 and it passed as StrPos returned a nil value when passing two '' param values. Has this been reported as a bug yet? ----------------- CUT ------------------- var lFrom: string; lSearch: string; lResult: PChar; begin lFrom := 'abc'; lSearch := 'b'; lResult := StrPos(Pointer(lFrom), Pointer(lSearch));

Eeeeuwww....

StrPos is expecting 2 PChar params and not a Pointer. Please use PChar(lFrom) and PChar(lSearch) to let the compiler make the proper string to PChar conversion.
You never ever can cast a string to a pchar using Pointer()

Marc

Show quoted text 26 lines
AssertEquals('Failing on 1', 'bc', string(lResult)); lSearch := 'x'; lResult := StrPos(Pointer(lFrom), Pointer(lSearch)); AssertEquals('Failing on 2', '', string(lResult)); lFrom := ''; lSearch := ''; lResult := StrPos(Pointer(lFrom), Pointer(lSearch)); AssertEquals('Failing on 3', '', string(lResult)); ----------------- END ------------------- Regards, - Graeme - _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Graeme Geldenhuys
to Jonas Maebe: No. I've fixed it and added a test. You can check whether something has been reported as…
Jonas Maebe wrote
No. I've fixed it and added a test. You can check whether something has been reported as a bug by going to http://www.freepascal.org/bugs.html

Thanks for that!

If possible, a copy of your unit tests would be nice addition to our test suite.

I will go through the unit and see what is appropriate. The unit I am working through now is like a coders toolbox, a bunch of utility fuctions.

In this test case we used our own implementation of StrPos, as Delphi's one is dog slow. Written in assembler, but slow nonetheless. Good news is that Free Pascal's implementation is even faster than ours. :-)

Regards,
- Graeme -

Reply by email

Graeme Geldenhuys
to Marc Weustink: Eeeeuwww.... StrPos is expecting 2 PChar params and not a Pointer. Please use…
Marc Weustink wrote
StrPos is expecting 2 PChar params and not a Pointer. Please use PChar(lFrom) and PChar(lSearch) to let the compiler make the proper string to PChar conversion. You never ever can cast a string to a pchar using Pointer()

I see your point, and amended my code. Nonetheless, Delphi never through a AV. I see Jonas created a fix for it though.

Regards,
- Graeme -

Reply by email

Jonas Maebe
to Graeme Geldenhuys
Graeme Geldenhuys wrote 7 lines
> StrPos is expecting 2 PChar params and not a Pointer. > Please use PChar(lFrom) and PChar(lSearch) to let the compiler > make the proper string to PChar conversion. > You never ever can cast a string to a pchar using Pointer() I see your point, and amended my code. Nonetheless, Delphi never through a AV. I see Jonas created a fix for it though.

It is very dangerous to rely on undocumented behaviour. At least the TP documentation does not specify what happens if you pass a null pchar to strpos, I don't know about Delphi. If you typecast an ansistring to a pchar, then the compiler makes sure that if the ansistring is empty (and thus a null pointer), a valid pointer to an empty null-terminated string is returned.

Jonas

Reply by email

Micha Nelissen
to Jonas Maebe
Jonas Maebe wrote
strpos, I don't know about Delphi. If you typecast an ansistring to a pchar, then the compiler makes sure that if the ansistring is empty (and thus a null pointer), a valid pointer to an empty null-terminated string is returned.

Is that not also undocumented behaviour ?

Micha

Reply by email

Jonas Maebe
to Micha Nelissen
Micha Nelissen wrote 6 lines
> strpos, I don't know about Delphi. If you typecast an ansistring > to a pchar, then the compiler makes sure that if the ansistring > is empty (and thus a null pointer), a valid pointer to an empty > null-terminated string is returned. Is that not also undocumented behaviour ?

I'm quite sure it isn't: afaik typecasting an ansistring to a pchar is fully supported. This means that an empty ansistring must result in an empty (as opposed to an invalid) pchar.

Jonas

Reply by email

peter green
to Micha Nelissen: Is that not also undocumented behaviour ? Micha
Show quoted text 16 lines
-----Original Message----- From: Behalf Of Micha Nelissen Sent: 12 December 2005 11:18 To: FPC developers' list Subject: Re: [fpc-devel] StrPos giving a access violation Jonas Maebe wrote: > strpos, I don't know about Delphi. If you typecast an ansistring to a > pchar, then the compiler makes sure that if the ansistring is empty > (and thus a null pointer), a valid pointer to an empty null-terminated > string is returned. Is that not also undocumented behaviour ?

its documented somewhere in the delphi help iirc

Reply by email

Michael Van Canneyt
to Jonas Maebe: I'm quite sure it isn't: afaik typecasting an ansistring to a pchar is fully supported.…
Jonas Maebe wrote 13 lines
On 12 dec 2005, at 12:17, Micha Nelissen wrote: >> strpos, I don't know about Delphi. If you typecast an ansistring to a >> pchar, then the compiler makes sure that if the ansistring is empty (and >> thus a null pointer), a valid pointer to an empty null-terminated string >> is returned. > > Is that not also undocumented behaviour ? I'm quite sure it isn't: afaik typecasting an ansistring to a pchar is fully supported. This means that an empty ansistring must result in an empty (as opposed to an invalid) pchar.

It's explicitly stated in the docs.

Michael.

Reply by email

Graeme Geldenhuys
to Jonas Maebe: I'm quite sure it isn't: afaik typecasting an ansistring to a pchar is fully supported.…
Jonas Maebe wrote 6 lines
> Is that not also undocumented behaviour ? I'm quite sure it isn't: afaik typecasting an ansistring to a pchar is fully supported. This means that an empty ansistring must result in an empty (as opposed to an invalid) pchar.

Taken from Delphi 7 help:

Mixing Delphi strings and null-terminated strings

* You can also use Pointer(S) to cast a long string to an untyped pointer. But if S is empty, the typecast returns nil.
* PChar(S) always returns a pointer to a memory block; if S is empty, a pointer to #0 is returned.

Regards,
- Graeme -

Reply by email

Micha Nelissen
to Graeme Geldenhuys
Graeme Geldenhuys wrote 8 lines
Taken from Delphi 7 help: Mixing Delphi strings and null-terminated strings * You can also use Pointer(S) to cast a long string to an untyped pointer. But if S is empty, the typecast returns nil. * PChar(S) always returns a pointer to a memory block; if S is empty, a pointer to #0 is returned.

Thanks, that is very ugly. That means that PChar(Pointer(MyStr)) is not the same as PChar(MyStr) which is not very pascalish IMHO, but ok.

I can understand that PChar(MyStr) to always return a valid pointer is a desirable property of course, but why not use a function instead that does this ? Useless question, of course.

Micha

Reply by email

Jonas Maebe
to Micha Nelissen
Micha Nelissen wrote 9 lines
> Taken from Delphi 7 help: > Mixing Delphi strings and null-terminated strings > * You can also use Pointer(S) to cast a long string to an untyped > pointer. But if S is empty, the typecast returns nil. > * PChar(S) always returns a pointer to a memory block; if S is > empty, a pointer to #0 is returned. Thanks, that is very ugly. That means that PChar(Pointer(MyStr)) is not the same as PChar(MyStr) which is not very pascalish IMHO, but ok.

It happens in more in Pascal. For example, single(longint_var) is also not the same as single(pointer(longint_var)) (let's assume a 32bit system). In the former case, the longint is convert to a floating point number with the same value. In the latter case, you get a floating point number with the same bit pattern as that original longint (which may be a valid or invalid floating point number, and whose value is almost certainly different from the longint's value, except in case of 0).

Jonas

Reply by email

Micha Nelissen
to Jonas Maebe
Jonas Maebe wrote 7 lines
It happens in more in Pascal. For example, single(longint_var) is also not the same as single(pointer(longint_var)) (let's assume a 32bit system). In the former case, the longint is convert to a floating point number with the same value. In the latter case, you get a floating point number with the same bit pattern as that original longint (which may be a valid or invalid floating point number, and whose value is almost certainly different from the longint's value, except in case of 0).

Oh, I thought always the second case happened. Apparantly not.

Micha

Reply by email

Jonas Maebe
to Micha Nelissen
Micha Nelissen wrote 10 lines
> It happens in more in Pascal. For example, single(longint_var) is > also not the same as single(pointer(longint_var)) (let's assume a > 32bit system). In the former case, the longint is convert to a > floating point number with the same value. In the latter case, > you get a floating point number with the same bit pattern as > that original longint (which may be a valid or invalid floating > point number, and whose value is almost certainly different from > the longint's value, except in case of 0). Oh, I thought always the second case happened. Apparantly not.

No, otherwise an implicit type conversion (e.g. passing a longint to a function which expects a floating point parameter) and an explicit typecase (as above) would have different results. Implicit type conversions are not always allowed (because of type safety), but when they are allowed they have the same effect as an explicit typecast.

Jonas

Reply by email