Fix Win64 type mismatch in IDataObject.HasFormat#292
Fix Win64 type mismatch in IDataObject.HasFormat#292csm101 wants to merge 4 commits intoTurboPack:masterfrom
Conversation
Use a Longint variable for IEnumFORMATETC.Next pceltFetched output. The COM API signature is Next(celt, out rgelt, pceltFetched: PLongint), so passing @returned where Returned was NativeInt produced an incompatible types error (PLongInt vs Pointer) on strict Win64 builds. This change makes the argument type match the API contract exactly.
Use a Longint variable for IEnumFORMATETC.Next pceltFetched output. The COM API signature is Next(celt, out rgelt, pceltFetched: PLongint), so passing @returned where Returned was NativeInt produced an incompatible types error (PLongInt vs Pointer) on strict Win64 builds. This change makes the argument type match the API contract exactly.
There was a problem hiding this comment.
Pull request overview
This PR fixes a Win64 strict-pointer type mismatch in HasFormat by aligning the local pceltFetched variable type with the COM IEnumFORMATETC.Next signature (which expects PLongint).
Changes:
- Update
ReturnedfromNativeInttoLongintso@ReturnedmatchesPLonginton strict Win64 builds.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…zing new multiline string syntax)
|
I have added another unrelated bugfix for a more serious issue: the syntax highlighter for Delphi has a bug in the code supporting the new syntax for multiline string literals (those enclosed by '''/''') that can make it enter into an endless loop for some malformed strings. this is a DUnitX unit test reproducing the issue: unit TestSynHighlighterDelphi;
interface
uses
DUnitX.TestFramework,
SynHighlighterDelphi;
type
[TestFixture]
TTestSynDelphiSynInfiniteLoop = class
private
procedure AssertLineScansWithoutHang(AHighlighter: TSynDelphiSyn;
const ALine: string; ALineNumber: Integer);
public
[Test] procedure Next_MultilineStringRange_AdvancesRunToEol;
[Test] procedure Next_EmptyLineInMultilineStringRange_AdvancesRunToEol;
[Test] procedure Next_MultilineStringDelimiterLine_DoesNotHang;
[Test] procedure Next_AnnotateStyleLineWithTripleQuote_AdvancesRunToEol;
end;
implementation
uses
System.SysUtils;
procedure TTestSynDelphiSynInfiniteLoop.AssertLineScansWithoutHang(
AHighlighter: TSynDelphiSyn; const ALine: string; ALineNumber: Integer);
const
MAX_ITERATIONS = 100000;
var
LIterations: Integer;
LPrevTokenPos: NativeInt;
begin
AHighlighter.SetLine(ALine, ALineNumber);
LIterations := 0;
while not AHighlighter.GetEol do
begin
LPrevTokenPos := AHighlighter.GetTokenPos;
AHighlighter.Next;
Inc(LIterations);
if (AHighlighter.GetTokenPos = LPrevTokenPos) and not AHighlighter.GetEol then
Assert.Fail(Format('Tokenizer stopped advancing at line %d. TokenPos=%d, Text="%s"',
[ALineNumber, LPrevTokenPos, ALine]));
if LIterations > MAX_ITERATIONS then
Assert.Fail(Format('Potential infinite loop at line %d. Iterations=%d, TokenPos=%d, Len=%d',
[ALineNumber, LIterations, AHighlighter.GetTokenPos, Length(ALine)]));
end;
end;
procedure TTestSynDelphiSynInfiniteLoop.Next_MultilineStringRange_AdvancesRunToEol;
var
LHighlighter: TSynDelphiSyn;
begin
LHighlighter := TSynDelphiSyn.Create(nil);
try
LHighlighter.ResetRange;
AssertLineScansWithoutHang(LHighlighter, 'x := ' + #39#39#39, 0);
AssertLineScansWithoutHang(LHighlighter, 'body line', 1);
finally
LHighlighter.Free;
end;
end;
procedure TTestSynDelphiSynInfiniteLoop.Next_EmptyLineInMultilineStringRange_AdvancesRunToEol;
var
LHighlighter: TSynDelphiSyn;
begin
LHighlighter := TSynDelphiSyn.Create(nil);
try
LHighlighter.ResetRange;
AssertLineScansWithoutHang(LHighlighter, 'x := ' + #39#39#39, 0);
AssertLineScansWithoutHang(LHighlighter, '', 1);
finally
LHighlighter.Free;
end;
end;
procedure TTestSynDelphiSynInfiniteLoop.Next_MultilineStringDelimiterLine_DoesNotHang;
var
LHighlighter: TSynDelphiSyn;
begin
LHighlighter := TSynDelphiSyn.Create(nil);
try
LHighlighter.ResetRange;
AssertLineScansWithoutHang(LHighlighter, 'x := ' + #39#39#39, 0);
AssertLineScansWithoutHang(LHighlighter, 'body line', 1);
AssertLineScansWithoutHang(LHighlighter, #39#39#39, 2);
Assert.AreEqual<NativeUInt>(NativeUInt(Pointer(rsMultilineString)),
NativeUInt(LHighlighter.GetRange));
finally
LHighlighter.Free;
end;
end;
procedure TTestSynDelphiSynInfiniteLoop.Next_AnnotateStyleLineWithTripleQuote_AdvancesRunToEol;
var
LHighlighter: TSynDelphiSyn;
begin
LHighlighter := TSynDelphiSyn.Create(nil);
try
LHighlighter.ResetRange;
AssertLineScansWithoutHang(LHighlighter,
'1.10 (user 01-Jan-24): S := ' + #39#39#39, 0);
AssertLineScansWithoutHang(LHighlighter,
'1.10 (user 01-Jan-24): hello world', 1);
finally
LHighlighter.Free;
end;
end;
end. |
Here the code was passing a pointer to a NativeInt variable (which can be either a 32 or 64 bit integer) to a function that explicitly expects a pointer to a LongInt variable (32 bit) regardless of the architecture
The COM API signature is Next(celt, out rgelt, pceltFetched: PLongint), so passing @returned where Returned was NativeInt produced an incompatible types error (PLongInt vs Pointer) on strict Win64 builds.
I noticed it only because I included this unit in a project where i did enable more strict type pointer checking for the @ operator, and it became a compilation error