Admins jonglieren fast täglich mit Quellcode. Shell- und Python-Skripte automatisieren Aufgaben, auf Servern laufen PHP- und Javascript-Anwendungen. Verantwortungsbewusste Admins testen ihre Software daher vor Inbetriebnahme, ein paar ausgeklügelte Tools sagen ihnen, wo es noch wehtut.
Ein nützliches Shellskript schreibt ein Admin im Alltagsstress schnell herunter – mitunter dauert es nur ein paar Tage, bis es ihm um die Ohren fliegt. Dann beginnt eine penible, zeitaufwändige und meist auch hektische Fehlersuche. Glücklicherweise existieren so genannte Static Code Analyzer.
Diese Werkzeuge untersuchen den Quellcode auf Fehler und typische Probleme. Sie spüren Tippfehler auf, die ein Mensch im Zeichensalat gern übersieht – von nicht initialisierten Variablen bis hin zu falsch gesetzten Semikola. Ob und wann ein Fehler vorliegt, entscheiden vorgegebene Prüfregeln. Die ergänzt der Programmierer bei manch einem Werkzeug noch um eigene Testkriterien.
Static heißen die Code Analyzer, weil sie sich lediglich den (statischen) Quellcode ansehen. Sie treffen somit keine Aussagen zum späteren Laufzeitverhalten. Immerhin führen einige Tools eine so genannte Datenflussanalyse durch und verfolgen Variablen durch den Programmcode. So spüren sie etwa ungenutzte oder überflüssige Variablen auf.
Bei dynamisch typisierten Programmiersprachen, etwa bei Python, steht der Typ einer Variablen allerdings erst zur Laufzeit fest. Die Analysewerkzeuge müssen dann erraten, welche Daten später zur Laufzeit in welchen Variablen liegen könnten. Das führt dazu, dass sie mitunter eigentlich korrekte Stellen als fehlerhaft anmahnen (False Positives).
Aufgehübscht
Viele Static Code Analyzer kreiden einen schlechten Programmierstil an und fungieren so nebenbei als Stylechecker. Dabei legen sie allgemein akzeptierte Coding Style Guides zugrunde – im Fall von Python etwa den PEP8-Standard [1]. Abschließend erzeugen einige der Tools Statistiken, die ebenfalls Hinweise auf Verbesserungen geben. Melden sie beispielsweise viele identische Zeilen, lagert der Entwickler diese, wo es passt, in eine eigene Funktion aus.
Die meisten Static Code Analyzer sind Kommandozeilen-Programme, die der Entwickler in (Shell-)Skripte oder eine eigene Toolchain einbindet. Nur einige bringen ein Frontend mit, das in der Regel bloß die Ausgaben der Kommandozeilen-Version anzeigt. Im Idealfall integrieren sich die Werkzeuge in Texteditoren oder IDEs. So stößt der Programmierer bereits bei der Code-Eingabe auf Fehler.
Zu den ersten Static Code Analyzern gehörte Lint (deutsch: Fussel). Es nahm C-Programme unter die Lupe und diente als Namengeber für zahlreiche ähnliche Tools. So kümmert sich Pylint um Python-Programme. Abgesehen vom ähnlichen Namen und demselben Grundprinzip haben diese Linter genannten Tools aber nichts miteinander gemein.
Javascript
Für Javascript gibt es gleich mehrere Linter (Tabelle 1), etwa JS-Lint von Douglas Crockford (Abbildung 1). Das Tool ist auch in Javascript geschrieben, Interessierte probieren es direkt auf der Homepage aus, der Quellcode wartet auf Github [2]. JS-Lint prüft neben der Syntax auch den Programmierstil und deckt einige strukturelle Probleme auf.
Tabelle 1
Static Code Analyzer für Javascript
|
Name |
Lizenz |
URL |
|---|---|---|
|
Closure Tools |
Apache License 2.0 |
|
|
Flow |
BSD-Lizenz |
|
|
ES-Lint |
MIT-Lizenz |
|
|
JS-Hint |
MIT Expat License und Json License |
|
|
JS-Lint |
eigene (Open Source) |
|
|
JS-Prime |
MIT-Lizenz |
|
|
Plato |
MIT-Lizenz |
|
|
Tajs |
Apache License 2.0 |
Das Tool geht restriktiver vor, als es der ECMA-Script-Standard in der Version 6 vorschreibt. So erzwingt es etwa ein Semikolon am Ende jeder Anweisung und verbietet den Operator »==« . JS-Lint unterliegt einer modifizierten MIT-Lizenz. Anwender dürfen das Tool nur für gute und nicht “für böse Zwecke” einsetzen. Die Free Software Foundation stuft die Lizenz daher als unfrei ein.
Eine Alternative ist JS-Hint. Es prüft wie JS-Lint die Syntax, beanstandet einen schlechten Programmstil und weist auf typische Probleme hin, etwa eine implizite Typkonvertierung. JS-Hint kennt in der aktuellen Version ECMA Script 3, 5.1 und 6. Das Tool lässt sich ebenfalls direkt auf seiner Homepage ausprobieren (Abbildung 2). Bei Bedarf integrieren Entwickler JS-Hint als Javascript-Modul in die eigenen Webseiten.
Daneben existiert es als Kommandozeilen-Version, die jedoch Node JS voraussetzt. Zudem fühlt sich JS-Hint in zahlreiche Texteditoren zu Hause, darunter Vim, Emacs, Sublime, Atom und Brackets. Das Tool unterliegt in einem Teil allerdings der Json-Lizenz, die eine ähnliche Klausel wie JS-Lint verwendet.
Unter einer reinen MIT-Lizenz steht ES-Lint. Im Gegensatz zu JS-Lint und JS-Hint verpackt das Tool jede Prüfregel in ein eigenes Plugin, das der Programmierer jederzeit ein- und ausschaltet – sogar zur Laufzeit. User steuern eigene Plugins bei. Die mitgelieferten Regeln decken Syntaxfehler ab, prüfen Best Practices (wie den Einsatz von »eval()« ), bemeckern zu komplexe Konstrukte und verweisen auf schlechten Programmierstil.
Das Tool unterstützt ECMA Script 6, Nutzer müssen den Support für den Standard aber explizit aktivieren. Sie testen ES-Lint direkt auf der Internetseite [3], eine ebenfalls verfügbare Kommandozeilen-Version setzt Node JS voraus.
Als Closure Tools stellt Google verschiedene Werkzeuge für Javascript-Programmierer bereit. Darunter befindet sich auch der Closure Compiler (Abbildung 3). Er verwandelt nicht nur Javascript-Anweisungen in “kompakten, hoch-performanten” Code, sondern führt nebenbei auch einen Syntaxcheck durch, prüft Variablen respektive ihre Typen und warnt vor typischen Problemen.
Der Closure Compiler lässt sich online auf Appspot nutzen [4], lokal als Java-Programm in einer Kommandozeilen-Version oder per REST-API ansprechen. Er unterstützt ECMA Script 3, 5 und Teile der Version 6. Als Ergänzung bietet Google den Closure Linter an, der den Programmierstil unter die Lupe nimmt [5]. Er folgt dabei dem Google Javascript Style Guide [6] und mahnt unter anderem fehlende Semikola an.
Das von Facebook entwickelte Flow stürzt sich primär auf den Datenfluss und untersucht Variableninhalte und ihre Typen. Es meckert beispielsweise, wenn eine Funktion etwas berechnet, der Programmierer sie aber mit einem Text aufruft. Flow durchforstet allerdings nur Javascript-Dateien, die der Entwickler mit einem entsprechenden Kommentar kennzeichnet. Mehr noch: Über zusätzliche Annotations an den Variablen gibt er deren gewünschte Typen vor.
Über entsprechende Plugins integriert er das Tool in Vim, Emacs und Nuclide. Zudem kann er Flow als Server betreiben, der Javascript-Dateien nach einer Änderung automatisch neu untersucht. Das Tool selbst ist in Ocaml verfasst.
Die Entwicklung von JS-Prime liegt zwar schon seit zwei Jahren auf Eis, das Tool klopft jedoch Javascript-Code explizit auf einige Sicherheitslücken ab. Darüber hinaus kommt es mit minifiziertem Java-Code zurecht. Der Nutzer bedient es über eine Weboberfläche.
Viele weitere im Internet verfügbare Tools spannen lediglich andere Kollegen ein. So greift Tajs auf den Closure Compiler zurück, während Plato das Duo JS-Hint und ES-Lint zur Arbeit schickt.
PHP
Auch PHP-Entwickler verfügen über diverse Helfer (Tabelle 2). Ähnlich wie Shells klopft auch PHP selbst den Quellcode zumindest auf Syntaxfehler ab. Anwender rufen es dazu mit dem Parameter »-l« auf und lassen es auf die entsprechende ».php« -Datei los.
Tabelle 2
Static Code Analyzer für PHP
|
Name |
Lizenz |
URL |
|---|---|---|
|
Phan |
MIT-Lizenz |
|
|
PHP-Codesniffer |
BSD-Lizenz |
|
|
PHP-Lint |
BSD-Lizenz |
|
|
PHPMD |
BSD-Lizenz |
|
|
Rips |
GPLv3 |
Über diese Möglichkeit hinaus geht PHP-Lint, das sowohl PHP-5- als auch PHP-7-Anwendungen verarbeitet (Abbildung 4, [7]). Neben der Suche nach Syntaxfehlern startet es unter anderem eine Datenflussanalyse, achtet auf korrekt durchgereichte Ausnahmen, prüft die Signaturen von Funktionen und stellt konsistente Typen sicher.
Entwickler greifen PHP-Lint unter die Arme, indem sie ihren Code mit speziellen Kommentaren spicken. Darin geben sie etwa explizit die Typen von Variablen vor. Als Bonus erstellt das Tool auf Wunsch eine Dokumentation direkt aus dem Quellcode. PHP-Lint ist selbst in PHP geschrieben und benötigt den PHP-Kommandozeilen-Interpreter PHP-CLI, den einige Distributionen in ein eigenes Paket stecken.
Als Alternative zu PHP-Lint positioniert sich der PHP Mess Detector (PHPMD, Abbildung 5). Er lehnt sich an den Static Code Analyzer JMD für Java an [8]. PHPMD sucht im Quellcode nicht nur mögliche Fehler, sondern auch suboptimalen Code, unnötig komplizierte Ausdrücke sowie nicht verwendete Parameter oder Methoden. Die Ergebnisse gibt PHPMD wahlweise im Text-, HTML- oder XML-Format aus. Obwohl das Tool bereits seit 2009 existiert, halten es die Entwickler noch für ein junges Projekt und entschuldigen damit die spärliche Anzahl mitgelieferter Prüfregeln.
Tatsächlich noch jung ist der komplett in PHP 7 programmierte Konkurrent Phan. Er testet unter anderem, ob der zugeführte Quellcode bereits unter PHP 7 läuft. Bei seinen Analysen berücksichtigt er zudem PHPDOC-Kommentare, etwa »@depricated« oder »@param« , sowie Generics, Namespaces, Traits und variadische Funktionen.
Besonders beliebt war lange Zeit Rips. Im Gegensatz zu den anderen Tools handelt es sich dabei um eine in PHP geschriebene Webanwendung. Ihr übergibt der PHP-Programmierer in einem Formular das zu prüfende Skript, woraufhin Rips zahlreiche, bunt aufbereitete Informationen ausspuckt (Abbildung 6). Insbesondere fahndet es nach Sicherheitslücken, darunter SQL Injections, Cross Site Scripting und Code Execution.
Der Vater von Rips entwickelt das Tool jedoch seit 2013 nicht mehr weiter. Lediglich ein paar Fehlerkorrekturen flossen in den vergangenen Jahren ein. Ursprünglich sollte es eine von Grund auf neu entwickelte Version 1.0 geben, von der allerdings jede Spur fehlt. Da Rips somit keine aktuellen Angriffstechniken kennt und zudem nicht mit modernen PHP-Versionen umgehen kann, lässt es sich nur noch für eine erste Einschätzung heranziehen.
Streng genommen gehört der PHP-Codesniffer nicht zu den Static Code Analyzern. Das Tool prüft, ob der Quellcode einem oder mehreren Codingstandards folgt. Zur Auswahl stehen unter anderem der Pear-Standard, PSR1 und PSR2. Dabei testet PHP-Codesniffer jedoch nebenbei auch ein paar typische Fehlerquellen, etwa nicht ordnungsgemäß deklarierte Funktionen. Die Ergebnisse liefert das Tool nicht nur in einer übersichtlichen Textmeldung, sondern auf Wunsch auch in mehreren Formaten, etwa XML, CSV oder Json. Den Prüfungen dürfen Anwender sogar »php.ini« -Einstellungen vorgeben. Ein Aufruf per
phpcs -d include_path=.:/php/includes test.php
würde beispielsweise den Include-Path beim Prüfen der Datei »test.php« um das Verzeichnis »/php/includes« ergänzen. PHP-Codesniffer verarbeitet bereits PHP-7-Anwendungen und analysiert als Bonus sogar eingeschränkt Javascript-Code.
Python
Es gibt verschiedene Python-Linter (Tabelle 3), zu den klassischen Static Code Analyzern zählt aber zweifelsohne Pylint. Auf Wunsch prüft das Tool den Code auf die Einhaltung des Python Coding Style Guide PEP 008. Pylint hilft außerdem beim Refactoring, indem es unter anderem doppelten Code aufspürt. Auf Wunsch generiert es aus dem Python-Code passende UML-Diagramme. Ein optionaler Parameter Documentation Checker prüft sogar, ob alle vom Python-Skript akzeptierten Parameter konsistent und für die späteren Anwender korrekt dokumentiert sind. Zudem erzeugt Pylint zahlreiche Statistiken, die unter anderem auch die Anzahl der duplizierten Zeilen auflisten.
Tabelle 3
Static Code Analyzer für Python
|
Name |
Lizenz |
URL |
|---|---|---|
|
Bandit |
Apache-2-Lizenz |
|
|
Flake8 |
MIT License |
|
|
Prospector |
GNU GPLv2 |
|
|
Pyflakes |
MIT License |
|
|
Pylint |
GNU GPLv2 |
Den Funktionsumfang des Tools dürfen Programmierer über Plugins erweitern. Auf Wunsch nutzt Pylint mehrere Prozessorkerne zugleich, was den Vorgang insbesondere bei umfangreichem Quellcode beschleunigt. Das Tool integriert sich außerdem in verschiedene IDEs und Texteditoren, darunter Emacs, Vim und Eclipse, und lässt sich in Continous Integration Tools wie Apycot, Hudson oder Jenkins nutzen. Seine Entwicklung treibt maßgeblich die Firma Logilab voran, die auch kommerzielle Dienste rund um Pylint anbietet.
Eine Alternative zu Pylint stellt Pyflakes. Es geht flotter zu Werke als die Konkurrenz, prüft den Programmierstil aber nicht. Zudem knöpft sich das Tool jede Skriptdatei einzeln vor und entdeckt mangels Überblick weniger Fehler.
Konkurrent Bandit (Abbildung 7) untersucht den Python-Code auf typische Sicherheitslücken, er empfiehlt sich somit zusätzlich zu Pylint und Pyflakes. Das aus dem Open-Stack-Universum stammende Tool prüft besonders die XML-Verarbeitung, den Netzwerkcode (vor allem FTP-, Telnet-, HTTP- und SSL-Verbindungen), problematische SQL-Abfragen sowie Verschlüsselung. Die absolvierten Tests schalten Anwender gezielt ein und aus oder ergänzen sie um eigene.
Auch für Python gibt es mehrere Tools, die andere Kollegen für die Analyse einspannen. So testet etwa Flake8 die ihm zugeführten Python-Skripte mit Hilfe von Pyflakes auf Fehler, kontrolliert unter Mitarbeit von Pep8 den Stil und erzeugt mit Ned Batchelders McCabe-Skript ein paar Statistiken. Der Kollege Prospector setzt neben Pylint und Pyflakes gleich bis zu acht weitere Tools auf den Quellcode an und bereitet deren Ausgaben auf.
Shell
Bleibt noch die Shell, die ebenfalls ein paar Helfer hat (Tabelle 4). Die meisten Shellinterpreter kennen den Kommandozeilen-Parameter »-n« . Mit ihm testen sie das übergebene Skript auf Syntaxfehler. Ergänzend gibt es noch den Parameter »-u« . Dank ihm stellt die Shell ihre Arbeit ein, sobald sie auf eine nicht definierte Variable zugreifen soll.
Tabelle 4
Static Code Analyzer für Shellskripte
|
Name |
Lizenz |
URL |
|---|---|---|
|
Bashate |
Apache License |
|
|
Checkbashisms |
GNU GPLv2 |
http://ftp.halifax.rwth-aachen.de/debian/pool/main/d/devscripts/ |
|
Shellcheck |
GNU GPLv3 |
Viele weitere Fehler deckt Shellcheck (Abbildung 8) auf. Darunter befinden sich falsch gesetzte Anführungszeichen, problematische Testabfragen, typische Anfängerfehler und sogar häufig genutzte, aber nicht optimale Kommandos. Darüber hinaus prüft Shellcheck den Programmierstil und kontrolliert, ob möglichst viele Shells das Skript verdauen können. Shellcheck integriert sich auf Wunsch in Vim, Emacs, Sublime und Atom. Das Tool präsentiert die Ergebnisse wahlweise als reinen Text, als XML-Daten oder im Json-Format.
Wer nur prüfen möchte, ob sein Shellskript auf möglichst vielen Interpretern läuft, greift alternativ zu Checkbashisms. Das Tool gehört zu Debians Devscripts und bemeckert alle Konstrukte, die nicht Posix-kompatibel sind. Einige Distributionen bieten Checkbashisms als eigenes Paket an, bei anderen steckt es im Devscripts-Paket.
Von den Open-Stack-Entwicklern gibt es schließlich noch Bashate, das einige wenige Stilprüfungen vollführt. Dazu zählen allerdings auch ein paar gefährliche beziehungsweise nicht empfohlene Befehle.
Fazit
Static Code Analyzer spüren schnell Fehler auf, die Skriptprogrammierer im Eifer des Gefechts leicht übersehen. Die Werkzeuge sind aber nur so clever, wie ihr Regelwerk. Das deckt jedoch normalerweise immer nur einen kleinen Teil aller problematischen Konstrukte ab.
Zudem untersuchen die im Artikel vorgestellten Werkzeuge nicht die Programmlogik. Sie bemerken also nicht, ob ein Onlineshop die Preise im Warenkorb multiplizieren oder doch besser nur addieren sollte. Entwickler sollten Static Code Analyzer folglich nicht als Allheilmittel verstehen, sondern lediglich als einen sinnvollen Baustein in einem umfassenden Testkonzept.
Infos
- PEP 0008 – Style Guide for Python Code: https://www.python.org/dev/peps/pep-0008/
- Quellcode zu JS-Lint: https://github.com/douglascrockford/JSLint
- ES-Lint online: http://eslint.org/demo/
- Closure Compiler online: http://closure-compiler.appspot.com/home
- Closure Linter: https://developers.google.com/closure/utilities/
- Google Javascript Style Guide: https://google.github.io/styleguide/javascriptguide.xml
- PHP-Lint online: http://www.icosaedro.it/phplint/phplint-on-line.html
- JMD: https://pmd.github.io














