From 1cabc1730bd510cf6dcb4d5998d3a6ed5366ae8d Mon Sep 17 00:00:00 2001 From: Martijn Laan <1092369+martijnlaan@users.noreply.github.com> Date: Wed, 15 May 2024 18:17:39 +0200 Subject: [PATCH] Improve previous: Use AnyString instead of const because types like Integer don't work because of the lack of 'var' in the prototypes. Putting 'var' + 'const' does not work at run time and was not able to fix this. Also improve AnyString: the compiler didn't actually check that an AnyString parameter in the call was actually a string type, instead it accepted any type as if the prototype said 'const'. --- Source/uPSC_classes.pas | 8 ++++---- Source/uPSCompiler.pas | 30 ++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/Source/uPSC_classes.pas b/Source/uPSC_classes.pas index 12d3f5a..dff4775 100644 --- a/Source/uPSC_classes.pas +++ b/Source/uPSC_classes.pas @@ -137,8 +137,8 @@ begin {$IFNDEF DELPHI_SYDNEY_UP} IsAbstract := True; {$ENDIF} - RegisterMethod('function Read(Buffer: const; Count: LongInt): LongInt'); - RegisterMethod('function Write(Buffer: const; Count: LongInt): LongInt'); + RegisterMethod('function Read(Buffer: AnyString; Count: LongInt): LongInt'); + RegisterMethod('function Write(Buffer: AnyString; Count: LongInt): LongInt'); {$IFDEF DELPHI_TOKYO_UP} {$IFNDEF PS_NOINT64} RegisterMethod('function Seek(Offset: Int64; Origin: Word): Int64'); @@ -146,8 +146,8 @@ begin {$ELSE} RegisterMethod('function Seek(Offset: LongInt; Origin: Word): LongInt'); {$ENDIF} - RegisterMethod('procedure ReadBuffer(Buffer: const; Count: LongInt)'); - RegisterMethod('procedure WriteBuffer(Buffer: const; Count: LongInt)'); + RegisterMethod('procedure ReadBuffer(Buffer: AnyString; Count: LongInt)'); + RegisterMethod('procedure WriteBuffer(Buffer: AnyString; Count: LongInt)'); {$IFDEF DELPHI4UP} {$IFNDEF PS_NOINT64} RegisterMethod('function CopyFrom(Source: TStream; Count: Int64): Int64'); diff --git a/Source/uPSCompiler.pas b/Source/uPSCompiler.pas index e219843..cac8e78 100644 --- a/Source/uPSCompiler.pas +++ b/Source/uPSCompiler.pas @@ -2755,6 +2755,20 @@ begin end; end; +function IsStringType(b: TPSBaseType): Boolean; +begin + case b of + btString{$IFNDEF PS_NOWIDESTRING}, btWideString, btUnicodeString{$ENDIF}: Result := True; + else + Result := False; + end; +end; + +function IsStringOrCharType(b: TPSBaseType): Boolean; +begin + Result := IsStringType(b) or IsCharType(b); +end; + function IsRealType(b: TPSBaseType): Boolean; begin case b of @@ -5254,9 +5268,8 @@ begin begin Params[c].ExpectedType := GetTypeNo(BlockInfo, Params[c].Val); if PType <> nil then - if (Params[c].ExpectedType = nil) or not (Params[c].ExpectedType.BaseType in [btString, - {$IFNDEF PS_NOWIDESTRING}btWideString, btUnicodeString, btWideChar,{$ENDIF} - btChar]) then begin + if (Params[c].ExpectedType = nil) or not IsStringOrCharType(Params[c].ExpectedType.BaseType) then + begin MakeError('', ecTypeMismatch, ''); Result := False; exit; @@ -9572,8 +9585,17 @@ begin end else begin - if (Tmp.ExpectedType = nil) or (Tmp.ExpectedType = FAnyString) then + if Tmp.ExpectedType = nil then + Tmp.ExpectedType := GetTypeNo(BlockInfo, tmp.Val) + else if Tmp.ExpectedType = FAnyString then begin Tmp.ExpectedType := GetTypeNo(BlockInfo, tmp.Val); + if not IsStringType(Tmp.ExpectedType.BaseType) then + begin + MakeError('', ecTypeMismatch, ''); + Cleanup; + exit; + end; + end; if Tmp.ExpectedType.BaseType = btPChar then begin Tmp.TempVar := AllocStackReg(at2ut(FindBaseType(btstring)))