You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Detektoren – Sonar-Prüfkatalog für das Static Code Analysis Tool for Delphi
Kanonische Liste der unterstützten und geplanten Code-Analyse-Regeln,
geordnet nach Schweregrad (Blocker → Critical → Major → Minor → Info).
Orientiert sich am Sonar-50er-Katalog plus eigene Bonus-Detektoren.
Status: ✅ implementiert | 🟡 teilweise | 🔲 offen
Zusammenfassung: 44 / 50 Sonar-Regel-Slots vollständig (Critical + Reliability + Maintainability + Minor weitestgehend abgedeckt) + 1 teilweise + 3 Bonus + 22 DFM-Detektoren + 32 SonarDelphi-Migration (SCA120-152) + 9 mORMot-Cluster (SCA153-161) + ~60 SonarDelphi-kompatible Naming-/Formatting-Checks (SCA060-119) + SCA164/165/166 (UnusedRoutine + UnusedSuppression + UninitVar-MVP) = ~165 Detektor-Kinds insgesamt (geliefert von ~158 Pipeline-Klassen; einige Klassen emittieren mehrere Kinds — z. B. uVisibilityCheck → 4 Kinds, uDfmAnalysisRunner → 22 DFM-Kinds).
Die 21 Pascal-AST-Detektoren unten folgen der Sonar-50-Taxonomie.
Die 22 DFM-Detektoren in eigenem Abschnitt sind formdatei-
spezifisch und gehören nicht in den Sonar-Katalog — sie arbeiten
auf dem DFM-Lexer + Parser + Komponentengraph (sowie FormBinder
für die Pascal-AST-Kopplung), eingeführt mit v0.10.0. Das
SonarDelphi-Migration-Cluster (SCA120-131) unten deckt Delphi-
spezifische Korrektheits-Checks ab, die SonarDelphi liefert und die
wir portiert haben. Die ~60 SCA060-119 Naming-/Formatting-Checks
sind hier noch nicht enumeriert — siehe rules/sca-rules.json
für die kanonische Liste.
📐 DFM-Detektoren — formdatei-spezifisch (nicht im 50er-Sonar-Katalog)
Diese laufen über .dfm-Dateien mit eigenem DFM-Lexer + Parser
Komponentengraph. TFormBinder koppelt die Form an den
zugehörigen .pas-AST, TDfmRepoIndex stellt Repo-weite
Cross-Form-Lookups bereit. Alle Detektoren liefern Vorher/Nachher-
Fix-Hints im Hilfe-Panel und haben DUnitX-Tests.
DFM-TField/TDataSource hat kein passendes published-Field in der Form-Klasse
Bug
uDfmSchemaMismatch
D5
DfmCircularDataSource
Zyklus in DataSource.DataSet / MasterSource — Endlosschleife / Stack-Overflow zur Laufzeit
Bug
uDfmCircularDataSource
D6
DfmFieldTypeMismatch
UI-Control-Klasse passt nicht zum TField-Datentyp (z.B. TDBEdit auf ftBlob)
Code Smell
uDfmFieldTypeMismatch
D7
DfmRequiredFieldUnbound / NotVisible
TField mit Required=True hat keine UI-Bindung (Unbound) — oder nur auf einem versteckten Tab (NotVisible)
Bug
uDfmRequiredField
Cluster Security (2) — Credentials & SQL-Injection in DFMs
#
Regel (fk…-ID)
Beschreibung
Typ
Unit
D8
DfmHardcodedDbCreds
Klartext-Credentials auf einer TADOConnection/TFDConnection-ConnectionString/Params-Property
Vulnerability
uDfmHardcodedDbCreds
D9
DfmSqlFromUserInput
SQL-Property einer DB-Query wird (im Pascal-Code) durch +-Verkettung mit TEdit.Text / anderer UI-Eingabe gebaut — DFM-Smell, der den Analyser zurück in den Pascal-AST zieht
Vulnerability
uDfmSqlFromUserInput
Cluster Layering / Architektur (4) — Trennung der Belange
#
Regel (fk…-ID)
Beschreibung
Typ
Unit
D10
DfmDbInUiForm
DB-Komponente (TADOConnection, TFDQuery, TClientDataSet, …) sitzt direkt auf einem UI-Form statt in einem Data-Modul
Code Smell
uDfmDbInUiForm
D11
DfmCrossFormCoupling
Code in Form1 greift via globaler Form-Variable auf Form2.<field> zu
Bug
uDfmCrossFormCoupling
D12
DfmLayerViolation
Eingabe-Control sitzt direkt auf TForm statt in Panel / TFrame / TGroupBox
Code Smell
uDfmLayerViolation
D13
DfmForbiddenClass
Komponente nutzt eine via analyser.ini → [DfmDetectors] ForbiddenClasses= gesperrte Klasse
Code Smell
uDfmForbiddenClass
Cluster UI/UX (4) — Interaktions-Smells in der Form-Definition
#
Regel (fk…-ID)
Beschreibung
Typ
Unit
D14
DfmDuplicateBinding
Mehrere Komponenten binden denselben OnClick / dasselbe DataField etc. — typischer Copy-Paste-Bug
Bug
uDfmDuplicateBinding
D15
DfmTabOrderConflict
Zwei Geschwister-Controls auf demselben Parent haben denselben TabOrder-Wert
Code Smell
uDfmTabOrderConflict
D16
DfmGodHandler
Eine Methode hängt an ≥ N Komponenten-Events — God-Handler, der pro Belang aufgeteilt werden sollte
Code Smell
uDfmGodHandler
D17
DfmActionMismatch
Komponente hat Action= UND OnClick= gesetzt — der explizite OnClick gewinnt still, die TAction-Verklebung läuft ins Leere
Bug
uDfmActionMismatch
Cluster Naming / Lokalisierung (3) — Hygiene
#
Regel (fk…-ID)
Beschreibung
Typ
Unit
D18
DfmDefaultName
Komponente hat noch ihren Default-Namen (Button1, Edit2, …)
Code Smell
uDfmDefaultName
D19
DfmHardcodedCaption
UI-sichtbarer String (Caption, Hint, Text, …) als Literal im DFM statt via resourcestring / dxgettext
Code Smell
uDfmHardcodedCaption
D20
DfmHardcodedDbCreds — Param-Variante
(siehe D8 — selbe Unit, separate Finding-Kind für Param-Values vs. ConnectionString)
Zwölf Checks aus dem SonarDelphi-Regelsatz portiert. Sie decken
Delphi-spezifische Korrektheitslücken ab, die in der generischen
Sonar-50-Taxonomie nicht abgebildet sind: Exception-/Raise-Hygiene,
Function-Result-Disziplin, Typ-Cast-Fallen bei Free / Char / Unicode
sowie locale-abhängige Format-Aufrufe. Alle bringen Vorher/Nachher-
Fix-Hints im Hilfe-Panel und eine DUnitX-Test-Fixture mit.
ID
Regel
Beschreibung
Schweregrad
Typ
Unit
SCA120
MissingRaise
EFoo.Create('msg'); erzeugt ein Exception-Objekt ohne raise — der Fehlerpfad wird stillschweigend übersprungen
Neun Detektoren, die nach einem Audit der mORMot2-Sourcen
hinzugekommen sind. Sie zielen auf Muster, die in großen Low-Level-Delphi-Projekten
immer wieder auftreten: Locking-Primitiven, Raw-Heap-Allokation, Dynamic-Array-
Wachstum, Byte-Level-Puffer-Manipulation, PChar-Arithmetik, Multi-Target-with-Blöcke,
typisierte Exception-Handler, String-Casts aus rohen Pointern, Win64-Pointer-Arithmetik.
Alle bringen Vorher/Nachher-Fix-Hints und ein DUnitX-Fixture mit.
ID
Regel
Beschreibung
Severity
Type
Unit
SCA153
UnpairedLock
<id>.Lock / EnterCriticalSection / TMonitor.Enter mit passendem Unlock in derselben Routine, aber ohne umgebendes try/finally — eine Exception verliert das Lock und führt zum Deadlock
Warning
Bug
uUnpairedLock
SCA154
MoveSizeOfPointer
Move / FillChar / CopyMemory / ZeroMemory mit SizeOf(PXxx), wobei PXxx ein Pointer-Typ ist — kopiert nur 4/8 Bytes (Pointer-Größe), nicht den Zielpuffer
Warning
Bug
uMoveSizeOfPointer
SCA155
WithMultipleTargets
with A, B do (zwei oder mehr Komma-getrennte Ziele) — mehrdeutige Member-Auflösung; eine neue Methode an A oder B verändert still die Bedeutung des Bodies
Hint
Code Smell
uWithMultipleTargets
SCA156
GetMemWithoutFreeMem
GetMem / AllocMem / ReallocMem mit passendem FreeMem in derselben Routine, aber ohne umgebendes try/finally — eine Exception verliert den allokierten Heap-Buffer
Warning
Bug
uGetMemWithoutFreeMem
SCA157
SetLengthAppendInLoop
SetLength(arr, Length(arr) + N) innerhalb einer for/while/repeat-Schleife — O(n*n) Realloc-Aufwand; einmal vor der Schleife vergrößern oder Block-Grow benutzen
Warning
Code Smell
uSetLengthAppendInLoop
SCA158
PointerArithmeticOnString
PChar(s) +/- Offset (oder PAnsiChar / PWideChar) ohne vorherigen Empty-Check auf s — PChar('') ist NIL, Arithmetik auf nil führt zur Access-Violation
Warning
Bug
uPointerArithmeticOnString
SCA159
EmptyOnHandler
on E: SomeException do ; (oder leerer begin end) — typisierter Exception-Handler schluckt eine spezifische Exception still; schlimmer als except end weil die Typ-Annotation absichtlich wirkt
Warning
Bug
uEmptyOnHandler
SCA160
StringFromPointer
string(P) / AnsiString(P) / UTF8String(P) Cast aus P-Präfix-Pointer setzt Null-Terminator voraus — liest über das Buffer-Ende hinaus wenn Terminator fehlt; Heap-Overread
Warning
Bug
uStringFromPointer
SCA161
PointerSubtraction
Cardinal(P1) - Cardinal(P2) (oder Integer/LongWord/LongInt-Varianten) trunkiert die oberen 32 Bit eines 64-Bit-Pointers auf Win64; stattdessen PtrUInt/NativeInt benutzen