StrPas bug (was: converting PChar to String)

First of all, I am sorry for posting this reply so late (2 weeks!) but
I never received the previous article in my ISP's NewsServer :(  I just
found it in DejaNews (looking for something else...)

On 27 Jun 1997 Dr John Stockton <> wrote:

>This is my modified prohram :

>program StrBad ;
>uses {$IfDef Windows} WinCrt, {$EndIf} Strings ;
>const n = 50000 ; SL = 83 ;
>var R : record S : string [SL] ; Guard : char end ;
>p : PChar ;
>  GetMem(p, n+1) ;
>  FillChar(p^, n, '!') ;
>  Mem[Seg(p^):Ofs(p^)+n] := 0 ;
>  R.Guard := #251 ;
>  with R do begin Write(1) ;
>    S:=StrPas(p) ; Write(2) ;
>    StrDispose(p) ; Writeln(3) ;
>    WriteLn('  R: S=[', Length(S), ']"', S, '"; Guard="', Guard, '"') ;
>    end ;
>  Readln ;
>  end.
>In Real mode, the program runs, Guard is *NOT* affected;

It is not Guard that is affected! Remember that the command S:=StrPas(p)
allocates 256 bytes in the stack for the function result. So what is
affected is what is written in the stack just above the space allocated
for the function result. If you put all the program portion shown above
in a procedure (so that s, Guard and p are allocated in the stack), you
will see that everything is messed up.

>but the PChar
>length seems to undergo "mod 256" within the function *before* the
>assignment truncates it to fit S.  Thus, if SL>Lo(n), S is shorter than
>it should be.  

The string length is assigned by "stosb", so the high byte is lost. But
the string data are transferred by "rep movsb" with cx=StrLen(p). So cx
characters are transferred, messing up whatever is located in the stack
just above the space allocated for the function result.

>I see StrCopy's on-line help admits to no length-checking.

StrCopy does not check that there is enough room in the destination
buffer (no function in the unit does such a check!). But we are talking
about StrPas which has no such declaration.

Hope this helps

Babis Athineos

S-mail: Papadoniou 61, 11145 Athens, Greece