integrated-application-development / sonar-delphi

Delphi language plugin for SonarQube
GNU Lesser General Public License v3.0
92 stars 13 forks source link

sonar-delphi crashes when the winapi "calling convention" is used #217

Closed Scharrels closed 4 months ago

Scharrels commented 4 months ago

Prerequisites

SonarDelphi version

1.4.0

SonarQube version

No response

Issue description

Delphi defines the winapi calling convention:

http://docwiki.embarcadero.com/RADStudio/Alexandria/en/Procedures_and_Functions_(Delphi)#Calling_Conventions

For all practical purposes this calling convention is equal to stdcall, but some old libraries still use this variant. sonar-delphi crashes when this calling convention is used:

ERROR: Error while processing <filename omitted>
au.com.integradev.delphi.file.DelphiFile$DelphiFileConstructionException: Failed to construct DelphiFile (line 1538:25 mismatched input 'winapi' expecting IMPLEMENTATION)
        at au.com.integradev.delphi.file.DelphiFile.setupFile(DelphiFile.java:159)
        at au.com.integradev.delphi.file.DelphiFile.from(DelphiFile.java:137)
        at au.com.integradev.delphi.symbol.SymbolTableBuilder.process(SymbolTableBuilder.java:284)
        at au.com.integradev.delphi.symbol.SymbolTableBuilder.processImportsWithInlineRoutines(SymbolTableBuilder.java:371)
        at au.com.integradev.delphi.symbol.SymbolTableBuilder.process(SymbolTableBuilder.java:293)
        at au.com.integradev.delphi.symbol.SymbolTableBuilder.indexUnit(SymbolTableBuilder.java:396)
        at au.com.integradev.delphi.symbol.SymbolTableBuilder.build(SymbolTableBuilder.java:477)
        at au.com.integradev.delphi.DelphiSensor.executeOnFiles(DelphiSensor.java:119)
        at au.com.integradev.delphi.DelphiSensor.execute(DelphiSensor.java:83)
        at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61)
        at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82)
        at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:201)
        at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:180)
        at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:398)
        at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:394)
        at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:363)
        at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:201)
        at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:180)
        at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:139)
        at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:201)
        at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:180)
        at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:71)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:65)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at jdk.proxy1/jdk.proxy1.$Proxy0.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
        at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:126)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:81)
        at org.sonarsource.scanner.cli.Main.main(Main.java:62)
Caused by: au.com.integradev.delphi.antlr.DelphiParser$ParserException: line 1538:25 mismatched input 'winapi' expecting IMPLEMENTATION
        at au.com.integradev.delphi.antlr.DelphiParser.reportError(DelphiParser.java:350)
        at au.com.integradev.delphi.antlr.DelphiParser.unitImplementation(DelphiParser.java:1945)
        at au.com.integradev.delphi.antlr.DelphiParser.unit(DelphiParser.java:1538)
        at au.com.integradev.delphi.antlr.DelphiParser.file(DelphiParser.java:487)
        at au.com.integradev.delphi.file.DelphiFile.createAST(DelphiFile.java:194)
        at au.com.integradev.delphi.file.DelphiFile.setupFile(DelphiFile.java:149)
        ... 38 common frames omitted
Caused by: org.antlr.runtime.MismatchedTokenException: null
        at org.antlr.runtime.BaseRecognizer.recoverFromMismatchedToken(BaseRecognizer.java:617)
        at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115)
        at au.com.integradev.delphi.antlr.DelphiParser.unitImplementation(DelphiParser.java:1881)
        ... 42 common frames omitted

Steps to reproduce

Analysing the attached Delphi unit using Sonar-Delphi triggers this issue.

Minimal Delphi code exhibiting the issue

unit Testing.Winapi;

interface

uses
  Winapi.Windows;

procedure SetThreadExecutionState(ESFlags: DWORD) ; winapi; external 'kernel32.dll' name 'SetThreadExecutionState';

implementation

end.
Cirras commented 4 months ago

Hi @Scharrels,

Thanks for the report. It looks like we're missing the winapi keyword in our Delphi grammar.

This should be an easy one - we'll have it fixed soon.