mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 01:09:25 +02:00
* use temporary location to construct writestr() string, because the
final destination may also be used in the other arguments (mantis #20744) git-svn-id: trunk@19678 -
This commit is contained in:
parent
55c17a94d6
commit
f67d7f08fc
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -11899,6 +11899,7 @@ tests/webtbs/tw2065.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw2069.pp svneol=native#text/plain
|
tests/webtbs/tw2069.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw20690.pp svneol=native#text/pascal
|
tests/webtbs/tw20690.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw2072.pp svneol=native#text/plain
|
tests/webtbs/tw2072.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw20744.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2109.pp svneol=native#text/plain
|
tests/webtbs/tw2109.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2110.pp svneol=native#text/plain
|
tests/webtbs/tw2110.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2128.pp svneol=native#text/plain
|
tests/webtbs/tw2128.pp svneol=native#text/plain
|
||||||
|
@ -507,15 +507,17 @@ Procedure fpc_Write_Text_Char_Iso(Len : Longint;var t : Text;c : Char); compiler
|
|||||||
Procedure fpc_Write_Text_WideChar(Len : Longint;var t : Text;c : WideChar); compilerproc;
|
Procedure fpc_Write_Text_WideChar(Len : Longint;var t : Text;c : WideChar); compilerproc;
|
||||||
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
||||||
|
|
||||||
function fpc_SetupWriteStr_Shortstr(out s: shortstring): PText; compilerproc;
|
{ all var rather than out, because they must not be trashed/finalized as they
|
||||||
|
can appear inside the other arguments of writerstr }
|
||||||
|
function fpc_SetupWriteStr_Shortstr(var s: shortstring): PText; compilerproc;
|
||||||
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
|
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
|
||||||
function fpc_SetupWriteStr_Ansistr(out s: ansistring): PText; compilerproc;
|
function fpc_SetupWriteStr_Ansistr(var s: ansistring): PText; compilerproc;
|
||||||
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
|
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
|
||||||
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
|
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
|
||||||
function fpc_SetupWriteStr_Unicodestr(out s: unicodestring): PText; compilerproc;
|
function fpc_SetupWriteStr_Unicodestr(var s: unicodestring): PText; compilerproc;
|
||||||
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
||||||
{$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
{$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
||||||
function fpc_SetupWriteStr_Widestr(out s: widestring): PText; compilerproc;
|
function fpc_SetupWriteStr_Widestr(var s: widestring): PText; compilerproc;
|
||||||
{$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
{$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
||||||
|
|
||||||
function fpc_SetupReadStr_Shortstr(const s: shortstring): PText; compilerproc;
|
function fpc_SetupReadStr_Shortstr(const s: shortstring): PText; compilerproc;
|
||||||
|
103
rtl/inc/text.inc
103
rtl/inc/text.inc
@ -1674,8 +1674,11 @@ End;
|
|||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
const
|
const
|
||||||
|
{ pointer to target string }
|
||||||
StrPtrIndex = 1;
|
StrPtrIndex = 1;
|
||||||
{ leave space for 128 bit string pointers :) (used for writestr) }
|
{ temporary destination for writerstr, because the original value of the
|
||||||
|
destination may be used in the writestr expression }
|
||||||
|
TempWriteStrDestIndex = 9;
|
||||||
ShortStrLenIndex = 17;
|
ShortStrLenIndex = 17;
|
||||||
{ how many bytes of the string have been processed already (used for readstr) }
|
{ how many bytes of the string have been processed already (used for readstr) }
|
||||||
BytesReadIndex = 17;
|
BytesReadIndex = 17;
|
||||||
@ -1691,7 +1694,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if (t.bufpos=0) then
|
if (t.bufpos=0) then
|
||||||
exit;
|
exit;
|
||||||
str:=pshortstring(ppointer(@t.userdata[StrPtrIndex])^);
|
str:=pshortstring(ppointer(@t.userdata[TempWriteStrDestIndex])^);
|
||||||
newbytes:=t.BufPos;
|
newbytes:=t.BufPos;
|
||||||
oldlen:=length(str^);
|
oldlen:=length(str^);
|
||||||
if (oldlen+t.bufpos > t.userdata[ShortStrLenIndex]) then
|
if (oldlen+t.bufpos > t.userdata[ShortStrLenIndex]) then
|
||||||
@ -1712,6 +1715,23 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure WriteStrShortFlush(var t: textrec);
|
||||||
|
begin
|
||||||
|
{ move written data from internal buffer to temporary string (don't move
|
||||||
|
directly from buffer to final string, because the temporary string may
|
||||||
|
already contain data in case the textbuf was smaller than the string
|
||||||
|
length) }
|
||||||
|
WriteStrShort(t);
|
||||||
|
{ move written data to original string }
|
||||||
|
move(PPointer(@t.userdata[TempWriteStrDestIndex])^^,
|
||||||
|
PPointer(@t.userdata[StrPtrIndex])^^,
|
||||||
|
t.userdata[ShortStrLenIndex]+1);
|
||||||
|
{ free temporary buffer }
|
||||||
|
freemem(PPointer(@t.userdata[TempWriteStrDestIndex])^);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
|
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
|
||||||
procedure WriteStrAnsi(var t: textrec);
|
procedure WriteStrAnsi(var t: textrec);
|
||||||
var
|
var
|
||||||
@ -1720,12 +1740,23 @@ var
|
|||||||
begin
|
begin
|
||||||
if (t.bufpos=0) then
|
if (t.bufpos=0) then
|
||||||
exit;
|
exit;
|
||||||
str:=pansistring(ppointer(@t.userdata[StrPtrIndex])^);
|
str:=pansistring(@t.userdata[TempWriteStrDestIndex]);
|
||||||
oldlen:=length(str^);
|
oldlen:=length(str^);
|
||||||
setlength(str^,oldlen+t.bufpos);
|
setlength(str^,oldlen+t.bufpos);
|
||||||
move(t.bufptr^,str^[oldlen+1],t.bufpos);
|
move(t.bufptr^,str^[oldlen+1],t.bufpos);
|
||||||
t.bufpos:=0;
|
t.bufpos:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure WriteStrAnsiFlush(var t: textrec);
|
||||||
|
begin
|
||||||
|
{ see comment in WriteStrShortFlush }
|
||||||
|
WriteStrAnsi(t);
|
||||||
|
pansistring(ppointer(@t.userdata[StrPtrIndex])^)^:=
|
||||||
|
pansistring(@t.userdata[TempWriteStrDestIndex])^;
|
||||||
|
{ free memory/finalize temp }
|
||||||
|
pansistring(@t.userdata[TempWriteStrDestIndex])^:='';
|
||||||
|
end;
|
||||||
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
|
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
|
||||||
|
|
||||||
|
|
||||||
@ -1737,12 +1768,23 @@ var
|
|||||||
begin
|
begin
|
||||||
if (t.bufpos=0) then
|
if (t.bufpos=0) then
|
||||||
exit;
|
exit;
|
||||||
str:=punicodestring(ppointer(@t.userdata[StrPtrIndex])^);
|
str:=punicodestring(@t.userdata[TempWriteStrDestIndex]);
|
||||||
setlength(temp,t.bufpos);
|
setlength(temp,t.bufpos);
|
||||||
move(t.bufptr^,temp[1],t.bufpos);
|
move(t.bufptr^,temp[1],t.bufpos);
|
||||||
str^:=str^+temp;
|
str^:=str^+temp;
|
||||||
t.bufpos:=0;
|
t.bufpos:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure WriteStrUnicodeFlush(var t: textrec);
|
||||||
|
begin
|
||||||
|
{ see comment in WriteStrShortFlush }
|
||||||
|
WriteStrUnicode(t);
|
||||||
|
punicodestring(ppointer(@t.userdata[StrPtrIndex])^)^:=
|
||||||
|
punicodestring(@t.userdata[TempWriteStrDestIndex])^;
|
||||||
|
{ free memory/finalize temp }
|
||||||
|
punicodestring(@t.userdata[TempWriteStrDestIndex])^:='';
|
||||||
|
end;
|
||||||
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
||||||
|
|
||||||
{$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
{$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
||||||
@ -1753,12 +1795,23 @@ var
|
|||||||
begin
|
begin
|
||||||
if (t.bufpos=0) then
|
if (t.bufpos=0) then
|
||||||
exit;
|
exit;
|
||||||
str:=pwidestring(ppointer(@t.userdata[StrPtrIndex])^);
|
str:=pwidestring(@t.userdata[TempWriteStrDestIndex]);
|
||||||
setlength(temp,t.bufpos);
|
setlength(temp,t.bufpos);
|
||||||
move(t.bufptr^,temp[1],t.bufpos);
|
move(t.bufptr^,temp[1],t.bufpos);
|
||||||
str^:=str^+temp;
|
str^:=str^+temp;
|
||||||
t.bufpos:=0;
|
t.bufpos:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure WriteStrWideFlush(var t: textrec);
|
||||||
|
begin
|
||||||
|
{ see comment in WriteStrShortFlush }
|
||||||
|
WriteStrWide(t);
|
||||||
|
pwidestring(ppointer(@t.userdata[StrPtrIndex])^)^:=
|
||||||
|
pwidestring(@t.userdata[TempWriteStrDestIndex])^;
|
||||||
|
{ free memory/finalize temp }
|
||||||
|
finalize(pwidestring(@t.userdata[TempWriteStrDestIndex])^);
|
||||||
|
end;
|
||||||
{$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
{$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
||||||
|
|
||||||
procedure SetupWriteStrCommon(out t: textrec);
|
procedure SetupWriteStrCommon(out t: textrec);
|
||||||
@ -1774,55 +1827,65 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function fpc_SetupWriteStr_Shortstr(out s: shortstring): PText; compilerproc;
|
function fpc_SetupWriteStr_Shortstr(var s: shortstring): PText; compilerproc;
|
||||||
begin
|
begin
|
||||||
setupwritestrcommon(ReadWriteStrText);
|
setupwritestrcommon(ReadWriteStrText);
|
||||||
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
||||||
|
|
||||||
|
{ temporary destination (see comments for TempWriteStrDestIndex) }
|
||||||
|
getmem(PPointer(@ReadWriteStrText.userdata[TempWriteStrDestIndex])^,high(s)+1);
|
||||||
|
setlength(pshortstring(ppointer(@ReadWriteStrText.userdata[TempWriteStrDestIndex])^)^,0);
|
||||||
|
|
||||||
ReadWriteStrText.userdata[ShortStrLenIndex]:=high(s);
|
ReadWriteStrText.userdata[ShortStrLenIndex]:=high(s);
|
||||||
setlength(s,0);
|
|
||||||
ReadWriteStrText.InOutFunc:=@WriteStrShort;
|
ReadWriteStrText.InOutFunc:=@WriteStrShort;
|
||||||
ReadWriteStrText.FlushFunc:=@WriteStrShort;
|
ReadWriteStrText.FlushFunc:=@WriteStrShortFlush;
|
||||||
result:=@ReadWriteStrText;
|
result:=@ReadWriteStrText;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
|
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
|
||||||
function fpc_SetupWriteStr_Ansistr(out s: ansistring): PText; compilerproc;
|
function fpc_SetupWriteStr_Ansistr(var s: ansistring): PText; compilerproc;
|
||||||
begin
|
begin
|
||||||
setupwritestrcommon(ReadWriteStrText);
|
setupwritestrcommon(ReadWriteStrText);
|
||||||
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
||||||
// automatically done by out-semantics
|
|
||||||
// setlength(s,0);
|
{ temp destination ansistring, nil = empty string }
|
||||||
|
PPointer(@ReadWriteStrText.userdata[TempWriteStrDestIndex])^:=nil;
|
||||||
|
|
||||||
ReadWriteStrText.InOutFunc:=@WriteStrAnsi;
|
ReadWriteStrText.InOutFunc:=@WriteStrAnsi;
|
||||||
ReadWriteStrText.FlushFunc:=@WriteStrAnsi;
|
ReadWriteStrText.FlushFunc:=@WriteStrAnsiFlush;
|
||||||
result:=@ReadWriteStrText;
|
result:=@ReadWriteStrText;
|
||||||
end;
|
end;
|
||||||
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
|
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
|
||||||
|
|
||||||
|
|
||||||
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
|
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
|
||||||
function fpc_SetupWriteStr_Unicodestr(out s: unicodestring): PText; compilerproc;
|
function fpc_SetupWriteStr_Unicodestr(var s: unicodestring): PText; compilerproc;
|
||||||
begin
|
begin
|
||||||
setupwritestrcommon(ReadWriteStrText);
|
setupwritestrcommon(ReadWriteStrText);
|
||||||
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
||||||
// automatically done by out-semantics
|
|
||||||
// setlength(s,0);
|
{ temp destination unicodestring, nil = empty string }
|
||||||
|
PPointer(@ReadWriteStrText.userdata[TempWriteStrDestIndex])^:=nil;
|
||||||
|
|
||||||
ReadWriteStrText.InOutFunc:=@WriteStrUnicode;
|
ReadWriteStrText.InOutFunc:=@WriteStrUnicode;
|
||||||
ReadWriteStrText.FlushFunc:=@WriteStrUnicode;
|
ReadWriteStrText.FlushFunc:=@WriteStrUnicodeFlush;
|
||||||
result:=@ReadWriteStrText;
|
result:=@ReadWriteStrText;
|
||||||
end;
|
end;
|
||||||
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
|
||||||
|
|
||||||
|
|
||||||
{$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
{$ifndef FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
||||||
function fpc_SetupWriteStr_Widestr(out s: widestring): PText; compilerproc;
|
function fpc_SetupWriteStr_Widestr(var s: widestring): PText; compilerproc;
|
||||||
begin
|
begin
|
||||||
setupwritestrcommon(ReadWriteStrText);
|
setupwritestrcommon(ReadWriteStrText);
|
||||||
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
PPointer(@ReadWriteStrText.userdata[StrPtrIndex])^:=@s;
|
||||||
// automatically done by out-semantics
|
|
||||||
// setlength(s,0);
|
{ temp destination widestring }
|
||||||
|
PWideString(@ReadWriteStrText.userdata[TempWriteStrDestIndex])^:='';
|
||||||
|
|
||||||
ReadWriteStrText.InOutFunc:=@WriteStrWide;
|
ReadWriteStrText.InOutFunc:=@WriteStrWide;
|
||||||
ReadWriteStrText.FlushFunc:=@WriteStrWide;
|
ReadWriteStrText.FlushFunc:=@WriteStrWideFlush;
|
||||||
result:=@ReadWriteStrText;
|
result:=@ReadWriteStrText;
|
||||||
end;
|
end;
|
||||||
{$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
{$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
|
||||||
|
44
tests/webtbs/tw20744.pp
Normal file
44
tests/webtbs/tw20744.pp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{ %opt=-gh }
|
||||||
|
|
||||||
|
program tt;
|
||||||
|
|
||||||
|
type
|
||||||
|
pstring = ^string;
|
||||||
|
var
|
||||||
|
s: string;
|
||||||
|
ps: pstring;
|
||||||
|
as: ansistring;
|
||||||
|
us: unicodestring;
|
||||||
|
ws: widestring;
|
||||||
|
begin
|
||||||
|
HaltOnNotReleased := true;
|
||||||
|
s:='abc';
|
||||||
|
ps:=@s;
|
||||||
|
writestr(s,ps^,1,s,2,s);
|
||||||
|
writeln(s);
|
||||||
|
if s<>'abc1abc2abc' then
|
||||||
|
halt(1);
|
||||||
|
|
||||||
|
as:='de';
|
||||||
|
as:=as+'f';
|
||||||
|
writestr(as,as,3,as,4,as);
|
||||||
|
writeln(as);
|
||||||
|
if as<>'def3def4def' then
|
||||||
|
halt(2);
|
||||||
|
|
||||||
|
|
||||||
|
us:='de';
|
||||||
|
us:=us+'f';
|
||||||
|
writestr(us,us,3,us,4,us);
|
||||||
|
writeln(as);
|
||||||
|
if us<>'def3def4def' then
|
||||||
|
halt(3);
|
||||||
|
|
||||||
|
|
||||||
|
ws:='de';
|
||||||
|
ws:=ws+'f';
|
||||||
|
writestr(ws,ws,3,ws,4,ws);
|
||||||
|
writeln(ws);
|
||||||
|
if ws<>'def3def4def' then
|
||||||
|
halt(4);
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user