diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 566bc03f7..adc8f5ff8 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -1,12 +1,10 @@ name: Gradle - on: pull_request: branches: - main - master - dev - jobs: gradle: strategy: @@ -16,17 +14,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - - name: Set up JDK 8 + - name: Set up JDK 11 uses: actions/setup-java@v4 with: distribution: temurin - java-version: 8 - + java-version: 11 - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 - with: - gradle-version: wrapper - - name: Build with Gradle run: ./gradlew build \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..c5f3f6b9c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 559f91427..d24f092ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM gradle:4.7.0-jdk8-alpine AS build +FROM gradle:5.6.2-jdk8 AS build COPY --chown=gradle:gradle . /home/gradle/src WORKDIR /home/gradle/src -RUN gradle build -x test --no-daemon +RUN gradle build -x test --no-daemon FROM openjdk:8-jre-slim diff --git a/README.md b/README.md index 98b93e909..b9b92d65b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A static code analysis tool for CFML. -License: [BSD](http://www.opensource.org/licenses/bsd-license.html) +License: [BSD](https://opensource.org/licenses/bsd-license.html) Current Version: 1.5.x @@ -43,15 +43,15 @@ The master branch is considered our stable codebase. Most of the development hap ## Using CFLint - Quickstart Guide -Get the latest version from [Maven Central](http://search.maven.org/#search%7Cga%7C1%7Ccflint) or the [CFLint GitHub release page](https://github.com/cflint/CFLint/releases) or build the project. +Get the latest version from [Maven Central](https://search.maven.org/search?q=cflint) or the [CFLint GitHub release page](https://github.com/cflint/CFLint/releases) or build the project. If you want to use CFLint from within another Maven project, use: ```xml com.github.cflint - CFLint - 1.4.0 + cflint + 1.4.1 ``` @@ -60,7 +60,7 @@ Or always use the latest: ```xml com.github.cflint - CFLint + cflint LATEST ``` @@ -69,7 +69,7 @@ With the binaries retrieved one or the other way, you can now use CFLint on the ### Use the "-all"-version of the jar-file - CFLint-1.5.0-all.jar +CFLint-1.5.0-all.jar ### Scan a folder with the complete set of rules @@ -234,7 +234,7 @@ The exception is debug mode. In debug mode, CFLint will always ignore user setti The flag `-html` instructs CFLint to create an HTML document. The full syntax is: - -html -html + -html -htmlfile ### XML @@ -549,7 +549,7 @@ Note: The back slashes must be escaped twice, once for JSON, once for regular ex Raise issues here on GitHub and we will look at them. -The [CFML Slack team](http://cfml-slack.herokuapp.com/) has a `#cflint` channel you can join and talk to most of the regular contributors and other users. +The [CFML Slack team](https://cfml-slack.herokuapp.com/) has a `#cflint` channel you can join and talk to most of the regular contributors and other users. # How to contribute diff --git a/build.gradle b/build.gradle index bb17b3bd2..42938a680 100644 --- a/build.gradle +++ b/build.gradle @@ -2,29 +2,45 @@ buildscript { repositories { mavenLocal() jcenter { - url "https://jcenter.bintray.com/" + url = "https://jcenter.bintray.com/" } maven { - url "https://oss.sonatype.org/content/repositories/snapshots/" + url = "https://oss.sonatype.org/content/repositories/snapshots/" } maven { - url "https://plugins.gradle.org/m2/" + url = "https://plugins.gradle.org/m2/" + } + maven { + url = "https://cfmlprojects.org/artifacts" } maven { - url "https://cfmlprojects.org/artifacts" + url "https://plugins.gradle.org/m2/" } } dependencies { classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1' classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.22.0" classpath "gradle.plugin.se.bjurr.gitchangelog:git-changelog-gradle-plugin:1.64" + // classpath "net.thebugmc.gradle:sonatype-central-portal-publisher:1.2.3" } } plugins { id 'java' - id 'com.github.johnrengelman.shadow' version '5.2.0' + id 'com.github.johnrengelman.shadow' version '7.1.1' id 'eclipse' + id 'signing' + // id 'net.thebugmc.gradle.sonatype-central-portal-publisher' version '1.2.3' +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(11) + vendor = JvmVendorSpec.ADOPTIUM + } + + withJavadocJar() + withSourcesJar() } // Helper functions and constants @@ -56,22 +72,31 @@ def getLatestTag = { -> apply plugin: "base" apply plugin: "signing" -apply plugin: "com.bmuschko.nexus" +//apply plugin: "com.bmuschko.nexus" apply plugin: 'java' -apply plugin: 'maven' +apply plugin: 'maven-publish' apply from: 'cobertura.gradle' -apply from: 'deploy.gradle' -apply plugin: "se.bjurr.gitchangelog.git-changelog-gradle-plugin" +//apply from: 'deploy.gradle' +apply plugin: 'se.bjurr.gitchangelog.git-changelog-gradle-plugin' +// apply plugin: "net.thebugmc.gradle.sonatype-central-portal-publisher" -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 1.11 +targetCompatibility = 1.11 repositories { - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - maven { url "https://repo.maven.apache.org/maven2" } - maven { url "https://oss.sonatype.org/content/repositories/releases" } - maven { url "https://cfmlprojects.org/artifacts" } + maven { + url = "https://oss.sonatype.org/content/repositories/snapshots" + } + maven { + url = "https://repo.maven.apache.org/maven2" + } + maven { + url = "https://oss.sonatype.org/content/repositories/releases" + } + maven { + url = "https://cfmlprojects.org/artifacts" + } } dependencies { implementation group: 'com.github.cfparser', name: 'cfml.parsing', version: '2.11.0' @@ -105,9 +130,9 @@ jar { attributes( 'Main-Class': 'com.cflint.cli.CFLintCLI', 'Implementation-Version': version, - 'Bundle-Name': 'CFLint', - 'Bundle-SymbolicName': 'com.cflint.CFLint', - 'Bundle-Description': 'CFLint', + 'Bundle-Name': 'cflint', + 'Bundle-SymbolicName': 'io.cfmleditor.cflint', + 'Bundle-Description': 'cflint', 'Bundle-ManifestVersion': 2, 'Bundle-Version': version ) @@ -117,14 +142,15 @@ jar { task fatJar(type: Jar) { manifest.from jar.manifest - classifier = 'all' + archiveClassifier.set('all') from { - configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } { exclude "META-INF/*.SF" exclude "META-INF/*.DSA" exclude "META-INF/*.RSA" } + duplicatesStrategy = DuplicatesStrategy.EXCLUDE with jar } @@ -154,3 +180,39 @@ task githubChangelogGenerator { println p.text } } + +tasks.register('stuffZip', Zip) { + archiveBaseName = 'stuff' + from 'src/stuff' +} + +// signing { +// sign stuffZip +// } + + +// centralPortal { +// pom { +// name = 'cfmleditor-cflint' +// description = 'cflint' +// url = "https://github.com/cfmleditor/CFLint/" +// licenses { +// license { +// name = "bsd-3-clause" +// url = "https://opensource.org/license/bsd-3-clause" +// } +// } +// developers { +// developer { +// name = "Gareth Edwards" +// email = "ghedwards@gmail.com" +// organization = "cfmleditor" +// organizationUrl = "https://github.com/cfmleditor/" +// } +// } +// scm { +// url = "https://github.com/cfmleditor/CFLint/" +// } +// } +// publishingType = USER_MANAGED +// } diff --git a/cobertura.gradle b/cobertura.gradle index 12df2586c..e69d8a9d4 100644 --- a/cobertura.gradle +++ b/cobertura.gradle @@ -1,7 +1,7 @@ logger.info "Configuring Cobertura Plugin" configurations{ - coberturaRuntime {extendsFrom testRuntime} + coberturaRuntime {extendsFrom testRuntimeOnly} } dependencies { @@ -15,7 +15,7 @@ def classesCopy="${classes}-copy" task cobertura(type: Test){ dependencies { - testRuntime 'net.sourceforge.cobertura:cobertura:1.9.4' + testRuntimeOnly 'net.sourceforge.cobertura:cobertura:1.9.4' } systemProperty "net.sourceforge.cobertura.datafile", serFile diff --git a/gradle.properties b/gradle.properties index 683a48d70..e399d7ee6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,12 @@ -#Tue, 06 Oct 2015 20:08:05 -0600 -group=com.github.cflint -version=1.5.0-SNAPSHOT -name=CFLint +#Mon, 18 Mar 2024 11:40:59 +1000 +group=io.github.cfmleditor +version=1.5.6-SNAPSHOT +name=cflint release=false -snapshot=false +snapshot=true +signing.keyId= +signing.password= +signing.secretKeyRingFile= +# sonatype credentials +centralPortal.username= +centralPortal.password= diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c0535..ccebba771 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 53b9e3802..9bf7bd339 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 8b35b5b74..ff917a9a0 100755 --- a/gradlew +++ b/gradlew @@ -1,67 +1,117 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -71,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -82,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -90,19 +140,22 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi # For Darwin, add options to specify how the application appears in the dock diff --git a/gradlew.bat b/gradlew.bat index 219d17f98..6689b85be 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,4 +1,20 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -9,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -24,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -38,7 +55,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -48,21 +65,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -70,17 +72,19 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..86b9dc520 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "CFLint", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/pom.xml b/pom.xml index fcecd2d98..81a28b814 100644 --- a/pom.xml +++ b/pom.xml @@ -1,18 +1,16 @@ 4.0.0 - com.github.cflint - CFLint - 1.5.0 + io.github.cfmleditor + cflint + 1.5.2 jar - CFLint - - A static code analysis tool for ColdFusion (in the spirit of FindBugs and Lint). With CFLint, you are able to analyze your ColdFusion code base for code violations. - - https://github.com/cflint/CFLint + cflint + A static code analysis tool for ColdFusion (in the spirit of FindBugs and Lint). With cflint, you are able to analyze your ColdFusion code base for code violations. + https://github.com/cfmleditor/cflint 2013 - CFLint + cflint @@ -34,19 +32,25 @@ cfparser https://github.com/denuno + + Gareth Edwards + ghedwards@gmail.com + cfmleditor + https://github.com/cfmleditor + - scm:git:git@github.com:cflint/CFLint.git - scm:git:git@github.com:cflint/CFLint.git - git@github.com:cflint/CFLint.git + scm:git:git@github.com:cfmleditor/cflint.git + scm:git:git@github.com:cfmleditor/cflint.git + git@github.com:cfmleditor/cflint.git cfmlprojects cfmlprojects - http://cfmlprojects.org/artifacts + https://cfmlprojects.org/artifacts sonatype @@ -57,10 +61,10 @@ - The New BSD License - http://www.opensource.org/licenses/bsd-license.html - repo - + The New BSD License + https://opensource.org/licenses/bsd-license.html + repo + @@ -70,7 +74,7 @@ 1.8 2.11.0 - 2.12.7.1 + 2.16.1 1.7.21 @@ -95,10 +99,25 @@ ant 1.10.14 + + org.glassfish.jaxb + jaxb-runtime + 2.3.5 + + + javax.xml.bind + jaxb-api + 2.3.0 + + + com.sun.xml.bind + jaxb-core + 2.3.0 + com.sun.xml.bind jaxb-impl - 2.1.17 + 2.3.0 com.fasterxml.jackson.core @@ -197,11 +216,11 @@ true - CFLint - com.cflint.CFLint - CFLint - 2 - ${project.version} + cflint + com.cflint.cflint + cflint + 2 + ${project.version} @@ -272,15 +291,15 @@ - org.apache.maven.plugins - maven-surefire-plugin - 2.18.1 - - 1 - true - -Xmx2g - - + org.apache.maven.plugins + maven-surefire-plugin + 3.2.2 + + 1 + true + -Xmx2g + + diff --git a/settings.gradle b/settings.gradle index c3184f3e4..e3802b2ea 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -rootProject.name = 'CFLint' +rootProject.name = 'cflint' \ No newline at end of file diff --git a/src/main/java/com/cflint/BugCounts.java b/src/main/java/com/cflint/BugCounts.java index 60d503382..acb118725 100644 --- a/src/main/java/com/cflint/BugCounts.java +++ b/src/main/java/com/cflint/BugCounts.java @@ -10,6 +10,11 @@ public class BugCounts { protected Map codeCounts = new HashMap<>(); protected int noBugs = 0; + + /** + * @param code code + * @param severity severity + */ public void add(final String code, final Levels severity) { if (severity == Levels.UNKNOWN) { return; diff --git a/src/main/java/com/cflint/BugInfo.java b/src/main/java/com/cflint/BugInfo.java index 14a9d3c10..49d91e2b2 100644 --- a/src/main/java/com/cflint/BugInfo.java +++ b/src/main/java/com/cflint/BugInfo.java @@ -24,6 +24,10 @@ public class BugInfo implements Comparable { private String component; private Levels severity = Levels.UNKNOWN; + + /** + * @return int + */ public int getLine() { return line; } diff --git a/src/main/java/com/cflint/BugList.java b/src/main/java/com/cflint/BugList.java index 0a184d367..4b9238b76 100644 --- a/src/main/java/com/cflint/BugList.java +++ b/src/main/java/com/cflint/BugList.java @@ -25,6 +25,10 @@ public BugList(final CFLintFilter filter) { this.filter = filter; } + + /** + * @return CFLintFilter + */ public CFLintFilter getFileFilter() { return fileFilter; } diff --git a/src/main/java/com/cflint/CF.java b/src/main/java/com/cflint/CF.java index d91cd8ba0..4404bde7e 100644 --- a/src/main/java/com/cflint/CF.java +++ b/src/main/java/com/cflint/CF.java @@ -445,6 +445,11 @@ public class CF { */ public static final String CLIENT = "client"; + /** + * CF scope client. + */ + public static final String FILE = "file"; + /** * CF scope arguments. */ @@ -485,6 +490,17 @@ public class CF { */ public static final String URL = "url"; + /** + * CFLocation tag. + */ + public static final String CFLOCATION = "cflocation"; + + /** + * CF attribute addtoken. + */ + public static final String ADDTOKEN = "addtoken"; + + private CF() { throw new IllegalStateException("CF utility class"); } diff --git a/src/main/java/com/cflint/CFLint.java b/src/main/java/com/cflint/CFLint.java index c2b23ceed..92c79e970 100644 --- a/src/main/java/com/cflint/CFLint.java +++ b/src/main/java/com/cflint/CFLint.java @@ -118,6 +118,7 @@ public class CFLint implements IErrorReporter { private boolean logError = false; private boolean quiet = false; private boolean debug = false; + private boolean threaded = false; private boolean showProgress = false; private boolean progressUsesThread = true; private CFLintStats stats = new CFLintStats(); @@ -146,6 +147,11 @@ public CFLint(final CFLintConfiguration configFile) throws IOException { } } + + /** + * @param configFile configFile + * @throws IOException IOException + */ public void setConfiguration(final CFLintConfiguration configFile) throws IOException { configuration = configFile == null ? new CFLintConfig() : configFile; extensions.clear(); @@ -210,9 +216,9 @@ public void setupConfigAncestry(File folder) { fileLoop: while (folder != null && folder.exists()) { for (final File file : folder.listFiles()) { if (file.getName().toLowerCase().equals(".cflintrc" + getEnvSuffix())) { - if (verbose) { - System.out.println("read config " + file); - } + // if (verbose) { + // System.out.println("read config " + file); + // } try { @SuppressWarnings("deprecation") final CFLintConfig newConfig = file.getName().toLowerCase().endsWith(".xml") @@ -341,6 +347,7 @@ public void process(final String src, final String filename) throws CFLintScanEx processStack(elements, " ", filename, null); } } + beforeEndFile(filename, new Context(filename, null, null, false, handler,configuration)); fireFinishedProcessing(filename); }catch(final Exception e){ throw new CFLintScanException(e); @@ -360,8 +367,8 @@ private int[] getLineOffsets(final String[] lines) { /** * 'Detect' if this is a pure cfscript component or interface * - * @param src - * @param elements + * @param src src + * @param elements elements * @return */ private boolean isComponentOrInterfaceScript(final String src, final List elements) { @@ -1018,12 +1025,28 @@ protected void scanExpression(final CFScriptStatement expression, final Context } } + protected void beforeEndFile(final String srcidentifier, final Context context) { + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try { + structurePlugin.beforeEndFile(srcidentifier, context, bugs); + for (final ContextMessage message : context.getMessages()) { + reportRule(message.getOriginalContext().getElement(), null, message.getOriginalContext(), (CFLintScanner) structurePlugin, message); + } + context.getMessages().clear(); + } catch (final Exception e) { + printException(e); + final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, context.startLine()); + reportRule(currentElement, null, context, null, cm); + } + } + } + /** * Register any overrides from multi-line comments. * - * @param context + * @param context context * The current context. - * @param functionToken + * @param functionToken functionToken * A token that points to the current function */ protected void registerRuleOverrides(final Context context, final Token functionToken) { @@ -1039,9 +1062,9 @@ protected void registerRuleOverrides(final Context context, final Token function } /** - * @param context + * @param context context * The current context. - * @param expression + * @param expression expression * The expression statement to check */ protected void registerRuleOverrides(final Context context, final CFExpressionStatement expression) { @@ -1073,9 +1096,9 @@ protected void registerRuleOverrides(final Context context, final CFExpressionSt /** * Register any overrides from comment elements before functions/components. * - * @param context + * @param context context * The current context. - * @param commentElement + * @param commentElement commentElement * The CFML comment element */ protected void applyRuleOverrides(final Context context, final Element commentElement) { @@ -1092,11 +1115,11 @@ protected void applyRuleOverrides(final Context context, final Element commentEl /** * - * @param expression + * @param expression expression * CF expression - * @param elem + * @param elem elem * Jericho HTML element - * @param oldcontext + * @param oldcontext oldcontext * The previous context */ private void process(final CFExpression expression, final Element elem, final Context oldcontext) { @@ -1201,6 +1224,8 @@ else if (expr instanceof CFArrayExpression) { for (final CFExpression child : (List)newExpr.getArgs()) { if(child instanceof CFAssignmentExpression){ process(((CFAssignmentExpression)child).getRight(), elem, context.subContextInAssignment(false)); + }else { + process(child, elem, context.subContextInAssignment(false)); } } } @@ -1218,7 +1243,7 @@ protected void reportRule(final Element elem, final Object expression, final Con /** * Returns the previous sibling of a given element * - * @param element + * @param element element * The Jericho HTML element object * @return the previous sibling of the given element. */ @@ -1242,9 +1267,9 @@ public static Element getPreviousSibling(final Element element) { /** * Check for in the tag hierarchy * - * @param element + * @param element element * The element to process - * @param msgcode + * @param msgcode msgcode * The message code to check for * @return true if the msgcode is disabled for the given element. */ @@ -1322,7 +1347,7 @@ public void reportRule(Element elem, Object currentExpression, final Context con } else if (AVOID_EMPTY_FILES.equals(msgcode)) { ruleInfo = new PluginInfoRule(); final PluginMessage msgInfo = new PluginMessage(AVOID_EMPTY_FILES); - msgInfo.setMessageText("CF file is empty: ${file}"); + msgInfo.setMessageText("CF file is empty: ${filename}"); msgInfo.setSeverity(Levels.WARNING); ruleInfo.getMessages().add(msgInfo); } else if (PARSE_ERROR.equals(msgcode)) { @@ -1485,6 +1510,10 @@ public void setVerbose(final boolean verbose) { this.verbose = verbose; } + public void setThreaded(final boolean threaded) { + this.threaded = threaded; + } + public void setLogError(final boolean logError) { this.logError = logError; } diff --git a/src/main/java/com/cflint/CFLintStats.java b/src/main/java/com/cflint/CFLintStats.java index 264bd5934..8db14fdca 100644 --- a/src/main/java/com/cflint/CFLintStats.java +++ b/src/main/java/com/cflint/CFLintStats.java @@ -32,6 +32,10 @@ public CFLintStats(final long timestamp, final long fileCount, final BigInteger this.counts = counts; } + + /** + * @param numberOfLines numberOfLines + */ public void addFile(final long numberOfLines) { fileCount++; totalLines = totalLines.add(BigInteger.valueOf(numberOfLines)); diff --git a/src/main/java/com/cflint/HTMLOutput.java b/src/main/java/com/cflint/HTMLOutput.java index 0326d9c43..bd307da42 100644 --- a/src/main/java/com/cflint/HTMLOutput.java +++ b/src/main/java/com/cflint/HTMLOutput.java @@ -27,6 +27,11 @@ public HTMLOutput(final String htmlStyle) { /** * Output bug list in HTML format. + * @param bugList bugList + * @param writer writer + * @param stats stats + * @throws IOException IOException + * @throws TransformerException TransformerException */ public void output(final BugList bugList, final Writer writer, final CFLintStats stats) throws IOException, TransformerException { diff --git a/src/main/java/com/cflint/JSONOutput.java b/src/main/java/com/cflint/JSONOutput.java index bcb9da51e..33487a0cd 100644 --- a/src/main/java/com/cflint/JSONOutput.java +++ b/src/main/java/com/cflint/JSONOutput.java @@ -21,7 +21,7 @@ public class JSONOutput extends StructuredOutput { private boolean prettyPrint = true; /** - * Return true if pretty output. + * @return true if pretty output. */ public boolean isPrettyPrint() { return prettyPrint; @@ -29,6 +29,7 @@ public boolean isPrettyPrint() { /** * Turn on / off pretty print. + * @param prettyPrint set prettyPrint boolean */ public void setPrettyPrint(final boolean prettyPrint) { this.prettyPrint = prettyPrint; @@ -36,6 +37,10 @@ public void setPrettyPrint(final boolean prettyPrint) { /** * Output bug list in JSON format. + * @param bugList bugList object + * @param writer document writer + * @param stats CFLint stats + * @throws IOException IOException */ public void output(final BugList bugList, final Writer writer, final CFLintStats stats) throws IOException { final BugCounts counts = stats.getCounts(); @@ -81,6 +86,8 @@ public void output(final BugList bugList, final Writer writer, final CFLintStats /** * Output JSON start of global object and version info. + * @param stats stats + * @param jg jg */ private void outputStart(final CFLintStats stats, final JsonGenerator jg) throws IOException { jg.writeStartObject(); @@ -92,6 +99,7 @@ private void outputStart(final CFLintStats stats, final JsonGenerator jg) throws /** * Output JSON end of global object. + * @param jg jg */ private void outputEnd(final JsonGenerator jg) throws IOException { // end global object @@ -102,6 +110,7 @@ private void outputEnd(final JsonGenerator jg) throws IOException { /** * Output JSON start of issues. + * @param jg jg */ private void outputStartIssues(final JsonGenerator jg) throws IOException { // start issues array @@ -111,6 +120,7 @@ private void outputStartIssues(final JsonGenerator jg) throws IOException { /** * Output JSON end of issues. + * @param jg jg */ private void outputCloseIssues(final JsonGenerator jg) throws IOException { // end issues array diff --git a/src/main/java/com/cflint/StackHandler.java b/src/main/java/com/cflint/StackHandler.java index a8a392739..6c608eb14 100644 --- a/src/main/java/com/cflint/StackHandler.java +++ b/src/main/java/com/cflint/StackHandler.java @@ -41,6 +41,10 @@ public StackHandler() { varStack.push(new Stack("")); } + + /** + * @param name name + */ public void addVariable(final String name) { varStack.peek().getVariables().add(name.toUpperCase()); } diff --git a/src/main/java/com/cflint/StructuredOutput.java b/src/main/java/com/cflint/StructuredOutput.java index 6810601a0..472ad6a4a 100644 --- a/src/main/java/com/cflint/StructuredOutput.java +++ b/src/main/java/com/cflint/StructuredOutput.java @@ -15,6 +15,9 @@ public class StructuredOutput { /** * Returns true if previous bug and current bug are grouped. + * @param prevbugInfo previous bugInfo object + * @param bugInfo bugInfo object + * @return boolean */ public boolean isGrouped(final BugInfo prevbugInfo, final BugInfo bugInfo) { if (prevbugInfo == null || bugInfo == null) { @@ -35,6 +38,9 @@ public boolean isGrouped(final BugInfo prevbugInfo, final BugInfo bugInfo) { /** * Returns true if a equals b and both are not null. + * @param a a + * @param b a + * @return boolean */ public boolean safeEquals(final String a, final String b) { return a != null && b != null && a.equals(b); @@ -42,6 +48,8 @@ public boolean safeEquals(final String a, final String b) { /** * Filename from path. + * @param filename fileName + * @return string */ public String filename(final String filename) { if (filename == null) { @@ -52,6 +60,8 @@ public String filename(final String filename) { /** * Returns two letter message code abbreviation. + * @param messageCode messageCode + * @return string */ public String abbrev(final String messageCode) { if (messageCode == null) { @@ -70,6 +80,8 @@ public String abbrev(final String messageCode) { /** * Return the value or an empty string if value is null. + * @param value value + * @return string */ public String notNull(final String value) { if (value == null) { diff --git a/src/main/java/com/cflint/TextOutput.java b/src/main/java/com/cflint/TextOutput.java index ba032a2a8..6edf91872 100644 --- a/src/main/java/com/cflint/TextOutput.java +++ b/src/main/java/com/cflint/TextOutput.java @@ -10,6 +10,13 @@ public class TextOutput { private static final String NEW_LINE = System.getProperty("line.separator"); + + /** + * @param bugList bugList + * @param sb sb + * @param stats stats + * @throws IOException IOException + */ public void output(final BugList bugList, final Writer sb, CFLintStats stats) throws IOException { final BugCounts counts = stats.getCounts(); @@ -18,10 +25,11 @@ public void output(final BugList bugList, final Writer sb, CFLintStats stats) th for (final BugInfo bugInfo : bugEntry.getValue()) { final String severity = bugEntry.getValue().get(0).getSeverity().toString(); final String code = bugEntry.getValue().get(0).getMessageCode(); + final Integer column = bugInfo.getColumn(); sb.append(NEW_LINE).append("Severity:").append(severity); sb.append(NEW_LINE).append("Message code:").append(code); sb.append(NEW_LINE).append("\tFile:").append(bugInfo.getFilename()); - sb.append(NEW_LINE).append("\tColumn:").append(Integer.toString(bugInfo.getColumn())); + sb.append(NEW_LINE).append("\tColumn:").append(Integer.toString(column > -1 ? column : 0)); sb.append(NEW_LINE).append("\tLine:").append(Integer.toString(bugInfo.getLine())); sb.append(NEW_LINE).append("\t\tMessage:").append(bugInfo.getMessage()); sb.append(NEW_LINE).append("\t\tVariable:'").append(bugInfo.getVariable()); diff --git a/src/main/java/com/cflint/Version.java b/src/main/java/com/cflint/Version.java index 913661a3c..7fb37bba1 100644 --- a/src/main/java/com/cflint/Version.java +++ b/src/main/java/com/cflint/Version.java @@ -8,6 +8,10 @@ private Version() { throw new IllegalStateException("Version utility class"); } + + /** + * @return String + */ public static String getVersion() { String version = CFLintCLI.class.getPackage().getImplementationVersion(); diff --git a/src/main/java/com/cflint/XMLOutput.java b/src/main/java/com/cflint/XMLOutput.java index d03677f38..e07904581 100644 --- a/src/main/java/com/cflint/XMLOutput.java +++ b/src/main/java/com/cflint/XMLOutput.java @@ -25,6 +25,10 @@ public class XMLOutput extends StructuredOutput { /** * Output bug list in XML format. + * @param bugList bugList + * @param writer writer + * @param stats stats + * @throws IOException IOException */ public void output(final BugList bugList, final Writer writer, final CFLintStats stats) throws IOException { final BugCounts counts = stats.getCounts(); @@ -139,6 +143,11 @@ private void outputCounts(final Writer writer, final CFLintStats stats, final Bu /** * Output findbugs XML format. + * @param bugList bugList + * @param writer writer + * @param stats stats + * @throws IOException IOException + * @throws TransformerException TransformerException */ public void outputFindBugs(final BugList bugList, final Writer writer, final CFLintStats stats) throws IOException, TransformerException { diff --git a/src/main/java/com/cflint/ant/CFLintTask.java b/src/main/java/com/cflint/ant/CFLintTask.java index faf1264c7..b1de95d02 100644 --- a/src/main/java/com/cflint/ant/CFLintTask.java +++ b/src/main/java/com/cflint/ant/CFLintTask.java @@ -152,6 +152,13 @@ public void execute() { } } + + /** + * @param xmlFile2 xmlFile2 + * @param encoding encoding + * @return Writer + * @throws IOException IOException + */ private Writer createWriter(final File xmlFile2, final Charset encoding) throws IOException { OutputStreamWriter out = null; FileOutputStream fos = null; diff --git a/src/main/java/com/cflint/api/CFLintAPI.java b/src/main/java/com/cflint/api/CFLintAPI.java index 22ce4c31c..3dadf202d 100644 --- a/src/main/java/com/cflint/api/CFLintAPI.java +++ b/src/main/java/com/cflint/api/CFLintAPI.java @@ -6,6 +6,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import org.apache.commons.io.IOUtils; @@ -37,6 +41,7 @@ public class CFLintAPI { boolean logError = false; boolean quiet = false; boolean debug = false; + boolean threaded = false; /** * List of file extensions to scan. Default to *.cfc and *.cfm @@ -59,15 +64,52 @@ public CFLintAPI() throws CFLintConfigurationException { this(new ConfigBuilder().build()); } - + + /** + * @param fileOrFolder fileOrFolder + * @return CFLintResult + * @throws CFLintScanException CFLintScanException + * @throws CFLintConfigurationException CFLintConfigurationException + */ public CFLintResult scan(final List fileOrFolder) throws CFLintScanException, CFLintConfigurationException { - for (final String scanfolder : fileOrFolder) { - cflint.scan(scanfolder); - } - for (final BugInfo bug : cflint.getBugs()) { - cflint.getStats().getCounts().add(bug.getMessageCode(), bug.getSeverity()); - } + /* if ( this.threaded ) { + + List> callableTasks = new ArrayList<>(); + int numThreads = Runtime.getRuntime().availableProcessors(); + ExecutorService executorService = Executors.newFixedThreadPool(numThreads); + + for (final String scanfolder : fileOrFolder) { + Callable callableTask = () -> { + cflint.scan(scanfolder); + return 1; + }; + callableTasks.add(callableTask); + } + + try { + executorService.invokeAll(callableTasks); + executorService.shutdown(); + executorService.awaitTermination(2, TimeUnit.MINUTES); + } catch (InterruptedException e) { + } + + for (final BugInfo bug : cflint.getBugs()) { + cflint.getStats().getCounts().add(bug.getMessageCode(), bug.getSeverity()); + } + + } else { */ + + for (final String scanfolder : fileOrFolder) { + cflint.scan(scanfolder); + } + + for (final BugInfo bug : cflint.getBugs()) { + cflint.getStats().getCounts().add(bug.getMessageCode(), bug.getSeverity()); + } + + // } + return new CFLintResult(cflint); } @@ -75,8 +117,7 @@ public CFLintResult scan(final String source) throws CFLintScanException, CFLint return scan(source, "source.cfc"); } - public CFLintResult scan(final String source, final String filename) - throws CFLintScanException { + public CFLintResult scan(final String source, final String filename) throws CFLintScanException { final File starterFile = new File(filename); if (starterFile.exists() && starterFile.getParentFile().exists()) { cflint.setupConfigAncestry(starterFile.getParentFile()); @@ -177,6 +218,18 @@ public void setVerbose(final boolean verbose) { } } + /** + * Threaded Scan + * + * @param threaded threaded scan + */ + public void setThreaded(final boolean threaded) { + this.threaded = threaded; + if(cflint != null) { + cflint.setThreaded(threaded); + } + } + /** * Log errors to standard error. * diff --git a/src/main/java/com/cflint/api/CFLintResult.java b/src/main/java/com/cflint/api/CFLintResult.java index a56a6d99c..02bb154d9 100644 --- a/src/main/java/com/cflint/api/CFLintResult.java +++ b/src/main/java/com/cflint/api/CFLintResult.java @@ -26,6 +26,11 @@ public CFLintResult(final CFLint cflint) { this.cflint = cflint; } + + /** + * @return String + * @throws MarshallerException MarshallerException + */ public String getXml() throws MarshallerException { final StringWriter xmlwriter = new StringWriter(); writeXml(xmlwriter); diff --git a/src/main/java/com/cflint/cli/CFLintCLI.java b/src/main/java/com/cflint/cli/CFLintCLI.java index 0d1607464..40ff7bf87 100644 --- a/src/main/java/com/cflint/cli/CFLintCLI.java +++ b/src/main/java/com/cflint/cli/CFLintCLI.java @@ -63,6 +63,11 @@ public class CFLintCLI { private boolean strictInclude; private String environmentName; + + /** + * @param args args + * @throws Exception Exception + */ public static void main(final String[] args) throws Exception { final Options commandOptions = new Options(); final Options helpOptions = new Options(); diff --git a/src/main/java/com/cflint/config/CFLintChainedConfig.java b/src/main/java/com/cflint/config/CFLintChainedConfig.java index 3e58f345c..f1c9b4a24 100644 --- a/src/main/java/com/cflint/config/CFLintChainedConfig.java +++ b/src/main/java/com/cflint/config/CFLintChainedConfig.java @@ -34,6 +34,11 @@ public CFLintChainedConfig createNestedConfig(final CFLintConfiguration config) return config == null ? this : new CFLintChainedConfig(config, this); } + + /** + * @param pluginMessage pluginMessage + * @return boolean + */ @Override public boolean includes(final PluginMessage pluginMessage) { return config.includes(pluginMessage) diff --git a/src/main/java/com/cflint/config/CFLintConfig.java b/src/main/java/com/cflint/config/CFLintConfig.java index 576bad4fc..4521aa3df 100644 --- a/src/main/java/com/cflint/config/CFLintConfig.java +++ b/src/main/java/com/cflint/config/CFLintConfig.java @@ -25,6 +25,10 @@ public class CFLintConfig extends BaseConfig { private boolean inheritParent = true; + + /** + * @return HashMap + */ public HashMap getParameters() { return parameters; } diff --git a/src/main/java/com/cflint/config/CFLintConfiguration.java b/src/main/java/com/cflint/config/CFLintConfiguration.java index b51c444ca..639fac82d 100644 --- a/src/main/java/com/cflint/config/CFLintConfiguration.java +++ b/src/main/java/com/cflint/config/CFLintConfiguration.java @@ -26,6 +26,7 @@ public interface CFLintConfiguration { * get the property from the configuration. * This can be overriden with -DcheckerClass.propertyname=value * + * @param linter linter * @param name the name of the parameter * @return the value of the parameter */ diff --git a/src/main/java/com/cflint/config/CFLintPluginInfo.java b/src/main/java/com/cflint/config/CFLintPluginInfo.java index 09774e047..33d835e4f 100644 --- a/src/main/java/com/cflint/config/CFLintPluginInfo.java +++ b/src/main/java/com/cflint/config/CFLintPluginInfo.java @@ -24,6 +24,10 @@ public class CFLintPluginInfo { private List rules = new ArrayList<>(); private List ruleGroups = new ArrayList<>(); + + /** + * @return List + */ public List getRules() { return rules; } diff --git a/src/main/java/com/cflint/config/ConfigUtils.java b/src/main/java/com/cflint/config/ConfigUtils.java index c068f58a0..b575197ea 100644 --- a/src/main/java/com/cflint/config/ConfigUtils.java +++ b/src/main/java/com/cflint/config/ConfigUtils.java @@ -39,6 +39,11 @@ private ConfigUtils() { throw new IllegalStateException("ConfigUtils utility class"); } + + /** + * @return Marshaller + * @throws JAXBException JAXBException + */ @Deprecated public static Marshaller createMarshaller() throws JAXBException { if (CFLintConfigContext == null) { diff --git a/src/main/java/com/cflint/listeners/ProgressMonitorListener.java b/src/main/java/com/cflint/listeners/ProgressMonitorListener.java index 81e2c35c4..0779e3a26 100644 --- a/src/main/java/com/cflint/listeners/ProgressMonitorListener.java +++ b/src/main/java/com/cflint/listeners/ProgressMonitorListener.java @@ -14,6 +14,10 @@ public ProgressMonitorListener(final String progressLabel) { progressMonitor = new ProgressMonitor(null, progressLabel, "processing", 0, 1); } + + /** + * @param srcidentifier srcidentifier + */ @Override public void startedProcessing(final String srcidentifier) { if (progressMonitor.isCanceled()) { diff --git a/src/main/java/com/cflint/plugins/CFLintScanner.java b/src/main/java/com/cflint/plugins/CFLintScanner.java index 8d38e45f6..14a87e05f 100644 --- a/src/main/java/com/cflint/plugins/CFLintScanner.java +++ b/src/main/java/com/cflint/plugins/CFLintScanner.java @@ -20,6 +20,8 @@ public interface CFLintScanner { void endFile(String fileName, BugList bugs); + void beforeEndFile(String fileName, Context context, BugList bugs); + void startComponent(Context context, BugList bugs); void endComponent(Context context, BugList bugs); diff --git a/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java b/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java index a6d7b4c73..e717738d4 100644 --- a/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java +++ b/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java @@ -63,6 +63,7 @@ public void setParameter(final String name, final Object value) { * This can be overriden with -DcheckerClass.propertyname=value * * @param name the name of the parameter + * @param infoRules infoRules * @return the value of the parameter */ @Deprecated @@ -87,6 +88,9 @@ public String getParameter(final String name, final PluginInfoRule ... infoRules /** * @deprecated - Use context.getConfiguration().getParameterNotNull() + * @param name name + * @param infoRules infoRules + * @return string */ @Deprecated public String getParameterNotNull(final String name, final PluginInfoRule ... infoRules ) { @@ -98,6 +102,11 @@ public String getParameterNotNull(final String name, final PluginInfoRule ... in } /** * @deprecated - Use context.getConfiguration().getParameter() + * @param name name + * @param clazz clazz + * @param infoRules infoRules + * @param E + * @return E */ @SuppressWarnings("unchecked") @Deprecated @@ -130,16 +139,27 @@ public E getParameter(final String name, final Class clazz, final PluginI * Return parameter split by comma * * @param name the name of the parameter + * @param infoRules infoRules * @return the value of the parameter as a list of strings */ public List getParameterAsList(final String name, final PluginInfoRule ... infoRules ) { return Arrays.asList(getParameterNotNull(name,infoRules).split(",")); } + + /** + * @param expression expression + * @param context context + * @return int + */ public int currentLine(final CFExpression expression, final Context context) { return expression.getLine() + context.startLine() - 1; } + + /** + * @return Map + */ public Map getParams() { return params; } @@ -152,6 +172,14 @@ public void startFile(final String fileName, final BugList bugs) { //empty body for Adapter } + /** + * Default implementation does nothing + */ + @Override + public void beforeEndFile(final String fileName, final Context context, final BugList bugs) { + //empty body for Adapter + } + /** * Default implementation does nothing */ diff --git a/src/main/java/com/cflint/plugins/CFLintStructureListener.java b/src/main/java/com/cflint/plugins/CFLintStructureListener.java index bddef2cf9..e8abc046c 100644 --- a/src/main/java/com/cflint/plugins/CFLintStructureListener.java +++ b/src/main/java/com/cflint/plugins/CFLintStructureListener.java @@ -13,9 +13,9 @@ public interface CFLintStructureListener { /** * Called when processing of a new file has started * - * @param fileName + * @param fileName fileName * Name of the file that started - * @param bugs + * @param bugs bugs * List of errors reported */ void startFile(final String fileName, BugList bugs); @@ -23,19 +23,31 @@ public interface CFLintStructureListener { /** * Called when processing of current file has ended * - * @param fileName + * @param fileName fileName * Name of the file that finished - * @param bugs + * @param bugs bugs * List of errors reported */ void endFile(final String fileName, BugList bugs); + /** + * Called when processing of current file has almost ended + * + * @param fileName fileName + * Name of the file that finished + * @param context context + * Current context + * @param bugs bugs + * List of errors reported + */ + void beforeEndFile(final String fileName, Context context, BugList bugs); + /** * Called when processing a new component has started * - * @param context + * @param context context * Current context - * @param bugs + * @param bugs bugs * List of errors reported */ void startComponent(final Context context, BugList bugs); @@ -43,9 +55,9 @@ public interface CFLintStructureListener { /** * Called when processing of current component has ended * - * @param context + * @param context context * Current context - * @param bugs + * @param bugs bugs * List of errors reported */ void endComponent(final Context context, BugList bugs); @@ -53,9 +65,9 @@ public interface CFLintStructureListener { /** * Called when processing of a new function has started * - * @param context + * @param context context * Current context - * @param bugs + * @param bugs bugs * List of errors reported */ void startFunction(final Context context, BugList bugs); @@ -63,9 +75,9 @@ public interface CFLintStructureListener { /** * Called when processing of current function has ended * - * @param context + * @param context context * Current context - * @param bugs + * @param bugs bugs * List of errors reported */ void endFunction(final Context context, BugList bugs); diff --git a/src/main/java/com/cflint/plugins/Context.java b/src/main/java/com/cflint/plugins/Context.java index 5483f192d..d33e29ecf 100644 --- a/src/main/java/com/cflint/plugins/Context.java +++ b/src/main/java/com/cflint/plugins/Context.java @@ -36,6 +36,10 @@ public enum ContextType { private boolean inAssignmentExpression; private boolean inStructKeyExpression; + + /** + * @return boolean + */ public boolean isInStructKeyExpression() { return inStructKeyExpression; } diff --git a/src/main/java/com/cflint/plugins/core/AbortChecker.java b/src/main/java/com/cflint/plugins/core/AbortChecker.java index f756c232f..91952a012 100644 --- a/src/main/java/com/cflint/plugins/core/AbortChecker.java +++ b/src/main/java/com/cflint/plugins/core/AbortChecker.java @@ -10,6 +10,12 @@ @Extension public class AbortChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFAbortStatement) { diff --git a/src/main/java/com/cflint/plugins/core/AddTokenMissing.java b/src/main/java/com/cflint/plugins/core/AddTokenMissing.java new file mode 100644 index 000000000..48112851d --- /dev/null +++ b/src/main/java/com/cflint/plugins/core/AddTokenMissing.java @@ -0,0 +1,27 @@ +package com.cflint.plugins.core; + +import com.cflint.BugList; +import com.cflint.CF; +import com.cflint.plugins.CFLintScannerAdapter; +import com.cflint.plugins.Context; + +import net.htmlparser.jericho.Element; + +public class AddTokenMissing extends CFLintScannerAdapter { + + + /** + * @param element element + * @param context context + * @param bugs bugs + */ + @Override + public void element(final Element element, final Context context, final BugList bugs) { + if (element.getName().equals(CF.CFLOCATION)) { + final String outputAttr = element.getAttributeValue(CF.ADDTOKEN); + if (outputAttr == null || outputAttr.toLowerCase() == "yes" || outputAttr.toLowerCase() == "true") { + context.addMessage("ADDTOKEN_ATTR", element.getAttributeValue(CF.URL)); + } + } + } +} diff --git a/src/main/java/com/cflint/plugins/core/ArgDefChecker.java b/src/main/java/com/cflint/plugins/core/ArgDefChecker.java index f3e38bb67..1e298dd36 100644 --- a/src/main/java/com/cflint/plugins/core/ArgDefChecker.java +++ b/src/main/java/com/cflint/plugins/core/ArgDefChecker.java @@ -13,6 +13,12 @@ public class ArgDefChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFFuncDeclStatement) { diff --git a/src/main/java/com/cflint/plugins/core/ArgDefConditionChecker.java b/src/main/java/com/cflint/plugins/core/ArgDefConditionChecker.java index 77463be72..ed62ad346 100644 --- a/src/main/java/com/cflint/plugins/core/ArgDefConditionChecker.java +++ b/src/main/java/com/cflint/plugins/core/ArgDefConditionChecker.java @@ -13,6 +13,12 @@ public class ArgDefConditionChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFFuncDeclStatement) { diff --git a/src/main/java/com/cflint/plugins/core/ArgTypeChecker.java b/src/main/java/com/cflint/plugins/core/ArgTypeChecker.java index e1e31c611..e3a6fcbe2 100644 --- a/src/main/java/com/cflint/plugins/core/ArgTypeChecker.java +++ b/src/main/java/com/cflint/plugins/core/ArgTypeChecker.java @@ -12,6 +12,12 @@ public class ArgTypeChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFFuncDeclStatement) { diff --git a/src/main/java/com/cflint/plugins/core/ArgVarChecker.java b/src/main/java/com/cflint/plugins/core/ArgVarChecker.java index 7f0692148..cf90e0505 100644 --- a/src/main/java/com/cflint/plugins/core/ArgVarChecker.java +++ b/src/main/java/com/cflint/plugins/core/ArgVarChecker.java @@ -22,6 +22,12 @@ public class ArgVarChecker extends CFLintScannerAdapter { private Set unqualifiedExpression = new HashSet<>(); private Set alreadyReportedFullExpression = new HashSet<>(); + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (context.isInAssignmentExpression()){ diff --git a/src/main/java/com/cflint/plugins/core/ArgumentNameChecker.java b/src/main/java/com/cflint/plugins/core/ArgumentNameChecker.java index 40afc4382..6f76b739a 100644 --- a/src/main/java/com/cflint/plugins/core/ArgumentNameChecker.java +++ b/src/main/java/com/cflint/plugins/core/ArgumentNameChecker.java @@ -159,6 +159,14 @@ private void parseParameters(final ValidName name,CFLintConfiguration configurat * - Names that are too wordy * - Names that look like temporary variables * - Names having a prefix or postfix + * @param context context + * @param argument argument + * @param filename filename + * @param functionName functionName + * @param line line + * @param offset offset + * @param bugs bugs + * @param argExpr argExpr */ public void checkNameForBugs(final Context context, final String argument, final String filename, final String functionName, final int line, final int offset, final BugList bugs,final CFFunctionParameter argExpr) { diff --git a/src/main/java/com/cflint/plugins/core/ArrayNewChecker.java b/src/main/java/com/cflint/plugins/core/ArrayNewChecker.java index de47053c0..f7d225707 100644 --- a/src/main/java/com/cflint/plugins/core/ArrayNewChecker.java +++ b/src/main/java/com/cflint/plugins/core/ArrayNewChecker.java @@ -13,6 +13,12 @@ @Extension public class ArrayNewChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFExpressionStatement) { diff --git a/src/main/java/com/cflint/plugins/core/BooleanExpressionChecker.java b/src/main/java/com/cflint/plugins/core/BooleanExpressionChecker.java index 9b4400f29..e2b315e9c 100644 --- a/src/main/java/com/cflint/plugins/core/BooleanExpressionChecker.java +++ b/src/main/java/com/cflint/plugins/core/BooleanExpressionChecker.java @@ -10,6 +10,11 @@ public class BooleanExpressionChecker extends CFLintScannerAdapter { protected int lastLineNo = -1; + + /** + * @param fileName fileName + * @param bugs bugs + */ // Reset the last line number @Override public void startFile(final String fileName, final BugList bugs) { diff --git a/src/main/java/com/cflint/plugins/core/BuiltInFunctionChecker.java b/src/main/java/com/cflint/plugins/core/BuiltInFunctionChecker.java index dc7a55429..265103d8b 100644 --- a/src/main/java/com/cflint/plugins/core/BuiltInFunctionChecker.java +++ b/src/main/java/com/cflint/plugins/core/BuiltInFunctionChecker.java @@ -14,6 +14,12 @@ @Extension public class BuiltInFunctionChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (expression instanceof CFFunctionExpression) { diff --git a/src/main/java/com/cflint/plugins/core/CFCompareVsAssignChecker.java b/src/main/java/com/cflint/plugins/core/CFCompareVsAssignChecker.java index b90b84207..4882a5077 100644 --- a/src/main/java/com/cflint/plugins/core/CFCompareVsAssignChecker.java +++ b/src/main/java/com/cflint/plugins/core/CFCompareVsAssignChecker.java @@ -20,6 +20,12 @@ public class CFCompareVsAssignChecker extends CFLintScannerAdapter { CFSCRIPTLexer.XOR, CFSCRIPTLexer.AND, CFSCRIPTLexer.ANDOPERATOR, CFSCRIPTLexer.EQ, CFSCRIPTLexer.NEQ, CFSCRIPTLexer.CONTAINS); + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFExpressionStatement) { diff --git a/src/main/java/com/cflint/plugins/core/CFDebugAttributeChecker.java b/src/main/java/com/cflint/plugins/core/CFDebugAttributeChecker.java index a97400bde..bc7799612 100644 --- a/src/main/java/com/cflint/plugins/core/CFDebugAttributeChecker.java +++ b/src/main/java/com/cflint/plugins/core/CFDebugAttributeChecker.java @@ -13,6 +13,12 @@ @Extension public class CFDebugAttributeChecker extends CFLintScannerAdapter { + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(final Element element, final Context context, final BugList bugs) { final Attributes attributes = element.getAttributes(); diff --git a/src/main/java/com/cflint/plugins/core/CFQueryChecker.java b/src/main/java/com/cflint/plugins/core/CFQueryChecker.java index bb930cb31..92ed8d4f6 100644 --- a/src/main/java/com/cflint/plugins/core/CFQueryChecker.java +++ b/src/main/java/com/cflint/plugins/core/CFQueryChecker.java @@ -12,6 +12,12 @@ public class CFQueryChecker extends CFLintScannerAdapter { private static final String NEVER_USE_QUERY_IN_CFM = "NEVER_USE_QUERY_IN_CFM"; + + /** + * @param element element + * @param context context + * @param bugs bugs + */ // rule: don't allow tag in a .cfm file @Override public void element(final Element element, final Context context, final BugList bugs) { diff --git a/src/main/java/com/cflint/plugins/core/CFScopes.java b/src/main/java/com/cflint/plugins/core/CFScopes.java index 5415d1de1..35fc5d1ae 100644 --- a/src/main/java/com/cflint/plugins/core/CFScopes.java +++ b/src/main/java/com/cflint/plugins/core/CFScopes.java @@ -12,6 +12,11 @@ public class CFScopes { private static final Collection scopes = Arrays.asList(CF.URL, CF.FORM, CF.COOKIE, CF.CGI, CF.SERVER, CF.APPLICATION, CF.SESSION, CF.CLIENT, CF.REQUEST, CF.ARGUMENTS, CF.VARIABLES, CF.THIS, CF.LOCAL, CF.CFCATCH, CF.CFTHREAD); + + /** + * @param variable variable + * @return String[] + */ protected static String[] parts(final String variable) { return variable.toLowerCase().split("\\.|\\[|\\]"); } diff --git a/src/main/java/com/cflint/plugins/core/CFSwitchDefaultChecker.java b/src/main/java/com/cflint/plugins/core/CFSwitchDefaultChecker.java index 3e608c718..ce5775377 100644 --- a/src/main/java/com/cflint/plugins/core/CFSwitchDefaultChecker.java +++ b/src/main/java/com/cflint/plugins/core/CFSwitchDefaultChecker.java @@ -15,6 +15,12 @@ public class CFSwitchDefaultChecker extends CFLintScannerAdapter { private static final String CFSCRIPT_STATEMENT_REQUIRED = CF.DEFAULT; private static final String MESSAGE_CODE = "NO_DEFAULT_INSIDE_SWITCH"; + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { // see if expression is cfSwithStatement diff --git a/src/main/java/com/cflint/plugins/core/CFTagCaseChecker.java b/src/main/java/com/cflint/plugins/core/CFTagCaseChecker.java index 8b39de3b2..8a0f97b0f 100644 --- a/src/main/java/com/cflint/plugins/core/CFTagCaseChecker.java +++ b/src/main/java/com/cflint/plugins/core/CFTagCaseChecker.java @@ -11,6 +11,12 @@ public class CFTagCaseChecker extends CFLintScannerAdapter { private static final String CFTAG_PREFERRED_CASE = "CFTAG_PREFERRED_CASE"; + + /** + * @param element element + * @param context context + * @param bugs bugs + */ // rule: tag should be lowercase or camelCase @Override public void element(final Element element, final Context context, final BugList bugs) { diff --git a/src/main/java/com/cflint/plugins/core/CFXTagChecker.java b/src/main/java/com/cflint/plugins/core/CFXTagChecker.java index 6174ef0bc..8de540b6f 100644 --- a/src/main/java/com/cflint/plugins/core/CFXTagChecker.java +++ b/src/main/java/com/cflint/plugins/core/CFXTagChecker.java @@ -9,6 +9,12 @@ public class CFXTagChecker extends CFLintScannerAdapter { + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(final Element element, final Context context, final BugList bugs) { final String tagName = element.getName(); diff --git a/src/main/java/com/cflint/plugins/core/ComplexBooleanExpressionChecker.java b/src/main/java/com/cflint/plugins/core/ComplexBooleanExpressionChecker.java index 4c89218b2..5373019f3 100644 --- a/src/main/java/com/cflint/plugins/core/ComplexBooleanExpressionChecker.java +++ b/src/main/java/com/cflint/plugins/core/ComplexBooleanExpressionChecker.java @@ -10,6 +10,12 @@ public class ComplexBooleanExpressionChecker extends CFLintScannerAdapter { protected int complexThreshold = 10; + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (expression instanceof CFBinaryExpression) { diff --git a/src/main/java/com/cflint/plugins/core/ComponentDisplayNameChecker.java b/src/main/java/com/cflint/plugins/core/ComponentDisplayNameChecker.java index a34f3c449..6ab5fb2c9 100644 --- a/src/main/java/com/cflint/plugins/core/ComponentDisplayNameChecker.java +++ b/src/main/java/com/cflint/plugins/core/ComponentDisplayNameChecker.java @@ -9,6 +9,12 @@ public class ComponentDisplayNameChecker extends CFLintScannerAdapter { + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(final Element element, final Context context, final BugList bugs) { if (element.getName().equals(CF.CFCOMPONENT)) { diff --git a/src/main/java/com/cflint/plugins/core/ComponentLengthChecker.java b/src/main/java/com/cflint/plugins/core/ComponentLengthChecker.java index 8fbbc4fd5..ba49c64a1 100644 --- a/src/main/java/com/cflint/plugins/core/ComponentLengthChecker.java +++ b/src/main/java/com/cflint/plugins/core/ComponentLengthChecker.java @@ -13,6 +13,12 @@ public class ComponentLengthChecker extends LengthChecker { private static final int LENGTH_THRESHOLD = 500; + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFCompDeclStatement) { diff --git a/src/main/java/com/cflint/plugins/core/ComponentNameChecker.java b/src/main/java/com/cflint/plugins/core/ComponentNameChecker.java index 720173bfd..4767bb920 100644 --- a/src/main/java/com/cflint/plugins/core/ComponentNameChecker.java +++ b/src/main/java/com/cflint/plugins/core/ComponentNameChecker.java @@ -118,6 +118,12 @@ private void parseParameters(CFLintConfiguration configuration) throws ConfigErr * - Names that are too wordy * - Names that look like temporary variables * - Names having a prefix or postfix + * @param context context + * @param component component + * @param filename filename + * @param line line + * @param offset offset + * @param bugs bugs */ public void checkNameForBugs(final Context context, final String component, final String filename, final int line, final int offset, final BugList bugs) { diff --git a/src/main/java/com/cflint/plugins/core/CreateObjectChecker.java b/src/main/java/com/cflint/plugins/core/CreateObjectChecker.java index 6884eba0a..addccf08e 100644 --- a/src/main/java/com/cflint/plugins/core/CreateObjectChecker.java +++ b/src/main/java/com/cflint/plugins/core/CreateObjectChecker.java @@ -11,6 +11,12 @@ @Extension public class CreateObjectChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFExpressionStatement) { diff --git a/src/main/java/com/cflint/plugins/core/FileCaseChecker.java b/src/main/java/com/cflint/plugins/core/FileCaseChecker.java index 03ac7404b..397e067c3 100644 --- a/src/main/java/com/cflint/plugins/core/FileCaseChecker.java +++ b/src/main/java/com/cflint/plugins/core/FileCaseChecker.java @@ -9,6 +9,11 @@ @Extension public class FileCaseChecker extends CFLintScannerAdapter { + + /** + * @param fileName fileName + * @param bugs bugs + */ @Override public void startFile(final String fileName, final BugList bugs) { String actualFileName = fileName; diff --git a/src/main/java/com/cflint/plugins/core/FunctionCollisionChecker.java b/src/main/java/com/cflint/plugins/core/FunctionCollisionChecker.java index 7d5ff07f8..5fc2e7c13 100644 --- a/src/main/java/com/cflint/plugins/core/FunctionCollisionChecker.java +++ b/src/main/java/com/cflint/plugins/core/FunctionCollisionChecker.java @@ -61,6 +61,12 @@ public void expression(final CFScriptStatement expression, final Context context } } + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(Element element, Context context, BugList bugs) { final String elementName = element.getName(); diff --git a/src/main/java/com/cflint/plugins/core/FunctionLengthChecker.java b/src/main/java/com/cflint/plugins/core/FunctionLengthChecker.java index f549e38ff..04b7ecdae 100644 --- a/src/main/java/com/cflint/plugins/core/FunctionLengthChecker.java +++ b/src/main/java/com/cflint/plugins/core/FunctionLengthChecker.java @@ -13,6 +13,12 @@ public class FunctionLengthChecker extends LengthChecker { private static final int LENGTH_THRESHOLD = 100; + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFFuncDeclStatement) { diff --git a/src/main/java/com/cflint/plugins/core/FunctionTypeChecker.java b/src/main/java/com/cflint/plugins/core/FunctionTypeChecker.java index 6a9f6da29..42f9271ea 100644 --- a/src/main/java/com/cflint/plugins/core/FunctionTypeChecker.java +++ b/src/main/java/com/cflint/plugins/core/FunctionTypeChecker.java @@ -11,6 +11,12 @@ public class FunctionTypeChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFFuncDeclStatement) { diff --git a/src/main/java/com/cflint/plugins/core/GlobalVarChecker.java b/src/main/java/com/cflint/plugins/core/GlobalVarChecker.java index 72c681bd5..e06e6954b 100644 --- a/src/main/java/com/cflint/plugins/core/GlobalVarChecker.java +++ b/src/main/java/com/cflint/plugins/core/GlobalVarChecker.java @@ -11,6 +11,12 @@ public class GlobalVarChecker extends CFLintScannerAdapter { protected CFScopes scopes = new CFScopes(); + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if ((context.isInComponent() || context.isInFunction()) && expression instanceof CFFullVarExpression) { diff --git a/src/main/java/com/cflint/plugins/core/HintChecker.java b/src/main/java/com/cflint/plugins/core/HintChecker.java index 6c55c2b18..e101306ca 100644 --- a/src/main/java/com/cflint/plugins/core/HintChecker.java +++ b/src/main/java/com/cflint/plugins/core/HintChecker.java @@ -18,6 +18,7 @@ public class HintChecker extends CFLintScannerAdapter { * Check for missing hint attributes. * * @param message message to report. + * @param name name * @param expression expression to scan. * @param context expression context. */ diff --git a/src/main/java/com/cflint/plugins/core/ImplicitScopeChecker.java b/src/main/java/com/cflint/plugins/core/ImplicitScopeChecker.java new file mode 100644 index 000000000..4b6da2407 --- /dev/null +++ b/src/main/java/com/cflint/plugins/core/ImplicitScopeChecker.java @@ -0,0 +1,223 @@ +package com.cflint.plugins.core; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.Map; +import java.util.LinkedHashMap; + +import com.cflint.BugList; +import com.cflint.CF; +import com.cflint.plugins.CFLintScannerAdapter; +import com.cflint.plugins.Context; +import cfml.parsing.cfscript.CFExpression; +import cfml.parsing.cfscript.CFFullVarExpression; +import cfml.parsing.cfscript.CFIdentifier; +import cfml.parsing.cfscript.CFMember; +import cfml.parsing.cfscript.CFVarDeclExpression; +import net.htmlparser.jericho.Element; + +public class ImplicitScopeChecker extends CFLintScannerAdapter { + + /** + * Report each occurrence once per file/function + */ + // private Set alreadyReportedExpression = new HashSet<>(); + // private Set unqualifiedExpression = new HashSet<>(); + // private Set alreadyReportedFullExpression = new HashSet<>(); + + // LinkedHashMap is ordered. + protected Set implicitScopedVariables = new HashSet<>(); + protected Set scopedVariables = new HashSet<>(); + protected Set variableScopedVariables = new HashSet<>(); + + protected Map unscopedAssignedVariables = new LinkedHashMap<>(); + protected Map implicitIdentifierVariables = new LinkedHashMap<>(); + protected Boolean isCFM = false; + + private final Collection scopes = Arrays.asList(CF.APPLICATION, CF.ATTRIBUTES, CF.REQUEST, CF.SERVER, CF.SESSION, CF.CFTHREAD, CF.FORM, CF.URL, CF.CGI, CF.COOKIE, CF.CLIENT, CF.FILE, CF.CFCATCH); + private final Collection implicitscopes = Arrays.asList(CF.FORM, CF.URL, CF.CGI, CF.COOKIE, CF.CLIENT, CF.FILE, CF.CFCATCH); + private final Collection variablescopes = Arrays.asList(CF.VARIABLES); + + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ + @Override + public void expression(final CFExpression expression, final Context context, final BugList bugs) { + if(expression instanceof CFFullVarExpression) { + checkFullExpression((CFFullVarExpression) expression, context, bugs); + } else if (expression instanceof CFVarDeclExpression) { + checkExpression((CFVarDeclExpression)expression, context); + } else if (expression instanceof CFIdentifier) { + final String name = ((CFIdentifier) expression).getName(); + if ( name != null ) { + final boolean checkIsScope = isScope(name); + final boolean checkIsInFunction = context.isInFunction(); + final boolean checkIsCallStackVariable = checkIsInFunction == true ? context.getCallStack().checkVariable(name) : false; + + if ( !checkIsScope && ( !checkIsInFunction || !checkIsCallStackVariable ) ) { + if (context.isInAssignmentExpression() && !(expression.getParent() instanceof CFMember) ) { + if ( !context.isInStructKeyExpression() ) { + unscopedAssignedVariables.put(name.toLowerCase(), new VariableInfo(name, expression, context)); + //if ( context.isInAssignmentExpression() ) { + variableScopedVariables.add(name.toLowerCase()); + //} + } + } else { + if ( !context.isInStructKeyExpression() ) { + implicitIdentifierVariables.put(name.toLowerCase(), new VariableInfo(name, expression, context)); + } + } + } + } + } + } + + private void checkFullExpression(final CFFullVarExpression expression, final Context context, final BugList bugs) { + final CFExpression variable = expression.getExpressions().get(0); + final CFExpression variable2 = expression.getExpressions().size() > 1 ? expression.getExpressions().get(1) : null; + if (variable instanceof CFIdentifier) { + final CFIdentifier cfIdentifier1 = (CFIdentifier) variable; + final CFIdentifier cfIdentifier2 = variable2 != null && variable2 instanceof CFIdentifier + ? (CFIdentifier) variable2 + /* : ( variable2 instanceof CFMember + ? (((CFMember) variable2).getExpression() instanceof CFIdentifier + ? (CFIdentifier) ((CFMember) variable2).getExpression() + : null ) */ + : null; + + final String name1 = ((CFIdentifier) cfIdentifier1).getName(); + if ( isImplicitScope(name1) && cfIdentifier2 != null ) { + final String name = ((CFIdentifier) cfIdentifier2).getName(); + if ( name != null ) { + implicitScopedVariables.add(name.toLowerCase()); + } + } else if ( isVariableScope(name1) && cfIdentifier2 != null ) { + final String name = ((CFIdentifier) cfIdentifier2).getName(); + if ( name != null ) { + variableScopedVariables.add(name.toLowerCase()); + } + } else if ( isScope(name1) && cfIdentifier2 != null ) { + final String name = ((CFIdentifier) cfIdentifier2).getName(); + if ( name != null ) { + scopedVariables.add(name.toLowerCase()); + } + } else if ( expression.getExpressions().size() == 1 ) { + if ( name1 != null ) { + final boolean checkIsInFunction = context.isInFunction(); + final boolean checkIsCallStackVariable = checkIsInFunction == true ? context.getCallStack().checkVariable(name1) : false; + if ( !checkIsInFunction || !checkIsCallStackVariable ) { + unscopedAssignedVariables.put(name1.toLowerCase(), new VariableInfo(name1,cfIdentifier1,context)); + if ( context.isInAssignmentExpression() ) { + variableScopedVariables.add(name1.toLowerCase()); + } + } + } + } + } + + for (CFExpression subexpr : expression.getExpressions()) { + if (subexpr instanceof CFMember) { + CFMember memberExpr = (CFMember) subexpr; + if (memberExpr.getExpression() != null) { + expression(memberExpr.getExpression(), context, bugs); + } + } + } + + } + + private void checkExpression(final CFVarDeclExpression expression, final Context context) { + // final String name = expression.getName(); + // implicitIdentifierVariables.put(name.toLowerCase(), new VariableInfo(name, expression, context)); + } + + @Override + public void startFile(String filename, BugList bugs) { + final String ext = filename.substring(filename.length() - 3, filename.length()); + isCFM = "cfm".equals(ext); + clearVariables(false); + } + + @Override + public void beforeEndFile(String filename, Context context, BugList bugs) { + checkImplicitScopes(false, context); + } + + @Override + public void startFunction(Context context, BugList bugs) { + clearVariables(true); + } + + @Override + public void endFunction(final Context context, final BugList bugs) { + checkImplicitScopes(true, context); + } + + @Override + public void element(final Element element, final Context context, final BugList bugs) { + } + + private void clearVariables(final Boolean isFunction) { + if ( (isFunction && isCFM) || (!isFunction && !isCFM) ) { + return; + } + implicitScopedVariables.clear(); + implicitIdentifierVariables.clear(); + unscopedAssignedVariables.clear(); + scopedVariables.clear(); + } + + private void checkImplicitScopes(final Boolean isFunction, final Context context) { + if ( (isFunction && isCFM) || (!isFunction && !isCFM) ) { + return; + } + // sort by line number + for (final VariableInfo variable : implicitIdentifierVariables.values()) { + // Doesn't exist as unscoped or VARIABLES, or is known as an implicit scope + if ( ( unscopedAssignedVariables.get(variable.name.toLowerCase()) == null + && variableScopedVariables.contains(variable.name.toLowerCase()) != true ) + || implicitScopedVariables.contains(variable.name.toLowerCase()) == true ) { + context.addMessage( + "IMPLICIT_SCOPE", + variable.name, + this, + variable.lineNumber, + variable.offset, + variable.expression, + variable.context); + } + } + } + + private boolean isImplicitScope(final String nameVar) { + return nameVar != null && implicitscopes.contains(nameVar.toLowerCase().trim()); + } + + private boolean isScope(final String nameVar) { + return nameVar != null && scopes.contains(nameVar.toLowerCase().trim()); + } + + private boolean isVariableScope(final String nameVar) { + return nameVar != null && variablescopes.contains(nameVar.toLowerCase().trim()); + } + + public static class VariableInfo { + private Integer lineNumber; + private Integer offset; + private String name; + CFExpression expression; + final Context context; + + public VariableInfo(final String name, final CFExpression expression,final Context context) { + super(); + this.name = name; + this.expression = expression; + this.context=context; + } + } +} diff --git a/src/main/java/com/cflint/plugins/core/LiteralChecker.java b/src/main/java/com/cflint/plugins/core/LiteralChecker.java index e19ed3e98..f86f93eda 100644 --- a/src/main/java/com/cflint/plugins/core/LiteralChecker.java +++ b/src/main/java/com/cflint/plugins/core/LiteralChecker.java @@ -24,6 +24,12 @@ public class LiteralChecker extends CFLintScannerAdapter { protected Map globalLiterals = new HashMap<>(); protected Map functionListerals = new HashMap<>(); + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ // May want to consider resetting literal map on new components but this way // it detects duplicated literals across files which is useful @@ -95,7 +101,7 @@ protected boolean isCommon(final String name) { /** * Checks if the literal is a special case that should not fire the literal checker rule * - * @param name + * @param name name * @return */ private boolean isSpecial(final String name) { diff --git a/src/main/java/com/cflint/plugins/core/MethodNameChecker.java b/src/main/java/com/cflint/plugins/core/MethodNameChecker.java index 0fc6d0a63..3ea60e7f8 100644 --- a/src/main/java/com/cflint/plugins/core/MethodNameChecker.java +++ b/src/main/java/com/cflint/plugins/core/MethodNameChecker.java @@ -104,6 +104,9 @@ private void parseParameters(CFLintConfiguration configuration) throws ConfigEr * - Names that are too wordy * - Names that look like temporary variables * - Names having a prefix or postfix + * @param context context + * @param line line + * @param offset offset */ public void checkNameForBugs(final Context context, final int line, final int offset) { final String method = context.getFunctionName(); diff --git a/src/main/java/com/cflint/plugins/core/NestedCFOutput.java b/src/main/java/com/cflint/plugins/core/NestedCFOutput.java index 6801c22d2..e20ea8e29 100644 --- a/src/main/java/com/cflint/plugins/core/NestedCFOutput.java +++ b/src/main/java/com/cflint/plugins/core/NestedCFOutput.java @@ -10,6 +10,12 @@ public class NestedCFOutput extends CFLintScannerAdapter { + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(final Element element, final Context context, final BugList bugs) { if (element.getName().equals(CF.CFOUTPUT)) { diff --git a/src/main/java/com/cflint/plugins/core/OutputParmMissing.java b/src/main/java/com/cflint/plugins/core/OutputParmMissing.java index 37268edf1..e0c600dc8 100644 --- a/src/main/java/com/cflint/plugins/core/OutputParmMissing.java +++ b/src/main/java/com/cflint/plugins/core/OutputParmMissing.java @@ -9,6 +9,12 @@ public class OutputParmMissing extends CFLintScannerAdapter { + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(final Element element, final Context context, final BugList bugs) { if (// element.getName().equals(CF.CFCOMPONENT) || diff --git a/src/main/java/com/cflint/plugins/core/PackageCaseChecker.java b/src/main/java/com/cflint/plugins/core/PackageCaseChecker.java index ac13baed9..e802c0ee9 100644 --- a/src/main/java/com/cflint/plugins/core/PackageCaseChecker.java +++ b/src/main/java/com/cflint/plugins/core/PackageCaseChecker.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.HashSet; import com.cflint.BugList; import com.cflint.CFLint; @@ -20,10 +21,16 @@ @Extension public class PackageCaseChecker extends CFLintScannerAdapter implements CFLintSet { - private final Map> componentRegister = new HashMap<>(); + private final Map> componentRegister = new HashMap<>(); private final Map> expressionCheckRegister = new HashMap<>(); private CFLint cflintRef; + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (expression instanceof CFFunctionExpression) { @@ -43,24 +50,32 @@ public void expression(final CFExpression expression, final Context context, fin } private boolean checkComponentRegister(final Context context, final String componentPath, final String componentName) { - if (componentRegister.containsKey(componentName.toLowerCase())) { - List filePathOfComponents = componentRegister.get(componentName.toLowerCase()); - for (String filePathOfComponent : filePathOfComponents) { - if (filePathOfComponent.toLowerCase().endsWith(componentPath.toLowerCase())) { - if (!filePathOfComponent.endsWith(componentPath)) { - final String expectedPath = filePathOfComponent.substring(filePathOfComponent.length() - componentPath.length()); + return checkComponentRegister(context, componentPath, componentName, false); + } + + private boolean checkComponentRegister(final Context context, final String componentPath, final String componentName, Boolean fromExpressionRegister) { + String lowerComponentName = componentName.toLowerCase(); + String lowerComponentPath = componentPath.toLowerCase(); + if (componentRegister.containsKey(lowerComponentName)) { + HashSet filePathOfComponents = componentRegister.get(lowerComponentName); + for (String[] filePathOfComponent : filePathOfComponents) { + if (filePathOfComponent[1].endsWith(lowerComponentPath)) { + if (!filePathOfComponent[0].endsWith(componentPath)) { + final String expectedPath = filePathOfComponent[0].substring(filePathOfComponent[0].length() - componentPath.length()); context.addMessage("PACKAGE_CASE_MISMATCH", expectedPath); } return true; } } } - //otherwise remember the component use for when component is first registered. - final String key = componentName.toLowerCase(); - if (!expressionCheckRegister.containsKey(key)) { - expressionCheckRegister.put(key, new ArrayList()); + if (!fromExpressionRegister) { + //otherwise remember the component use for when component is first registered. + final String key = lowerComponentName; + if (!expressionCheckRegister.containsKey(key)) { + expressionCheckRegister.put(key, new ArrayList()); + } + expressionCheckRegister.get(key).add(new PackageCaseCheckerEntry(context, componentPath, componentName)); } - expressionCheckRegister.get(key).add(new PackageCaseCheckerEntry(context, componentPath, componentName)); return false; } @@ -68,22 +83,34 @@ private boolean checkComponentRegister(final Context context, final String compo public void startComponent(final Context context, final BugList bugs) { final String key = context.getComponentName().toLowerCase(); if (!componentRegister.containsKey(key)) { - componentRegister.put(key, new ArrayList()); + componentRegister.put(key, new HashSet()); } - componentRegister.get(key).add(normalize(context.getFilename())); + String component_name=normalize(context.getFilename()); + componentRegister.get(key).add(new String[]{component_name, component_name.toLowerCase()}); //if an expression already referenced this component, check it here: boolean matched = false; if (expressionCheckRegister.containsKey(key)) { - List clonedList = new ArrayList<>(); + Map lookupCache = new HashMap(); + List clonedList = new ArrayList(); clonedList.addAll(expressionCheckRegister.get(key)); + boolean checkComponentRegisterResult = false; for (final PackageCaseCheckerEntry expressionEntry : clonedList) { - if (checkComponentRegister(expressionEntry.context, expressionEntry.componentPath, expressionEntry.componentName)) { + String cacheKey = expressionEntry.componentPath + "||" + expressionEntry.componentName; + if (!lookupCache.containsKey(cacheKey)) { + checkComponentRegisterResult = checkComponentRegister(expressionEntry.context, expressionEntry.componentPath, expressionEntry.componentName, true); + lookupCache.put(cacheKey, checkComponentRegisterResult); + } else { + checkComponentRegisterResult = lookupCache.get(cacheKey); + } + + if (checkComponentRegisterResult) { matched = true; for (ContextMessage message : expressionEntry.context.getMessages()) { cflintRef.reportRule(expressionEntry.context.getElement(), null, expressionEntry.context, this, message); } expressionEntry.context.getMessages().clear(); + break; } } } diff --git a/src/main/java/com/cflint/plugins/core/QueryParamChecker.java b/src/main/java/com/cflint/plugins/core/QueryParamChecker.java index 75f956f80..e3a0a63bd 100644 --- a/src/main/java/com/cflint/plugins/core/QueryParamChecker.java +++ b/src/main/java/com/cflint/plugins/core/QueryParamChecker.java @@ -4,6 +4,8 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.io.StringReader; +import java.io.BufferedReader; import com.cflint.BugList; import com.cflint.CF; @@ -16,6 +18,12 @@ public class QueryParamChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (expression instanceof CFFunctionExpression) { @@ -36,18 +44,33 @@ public void element(final Element element, final Context context, final BugList if ( element.getName().equalsIgnoreCase(CF.CFQUERY) && !CF.QUERY.equalsIgnoreCase(element.getAttributeValue(CF.DBTYPE))) { String content = element.getContent().toString(); + final String allowVariableExpression = context.getConfiguration().getParameter(this,"allowVariableExpression"); + Pattern allowVariableExpressionPattern = null; + if ( !"".equals(allowVariableExpression) ) { + allowVariableExpressionPattern = Pattern.compile(allowVariableExpression,Pattern.DOTALL); + } + final String allowLineExpression = context.getConfiguration().getParameter(this,"allowLineExpression"); //Todo : cfparser/Jericho does not support parsing out the cfqueryparam very well. // the following code will not work when there is a > sign in the expression content = content.replaceAll("<[cC][fF][qQ][uU][eE][rR][yY][pP][aA][rR][aA][mM][^>]*>", ""); if (content.indexOf('#') >= 0) { - final List ignoreLines = determineIgnoreLines(element); + final List ignoreLines = determineIgnoreLines(content, context.startLine()); final Matcher matcher = Pattern.compile("#(?:##)?([^#]+)(?:##)?#($|[^#])",Pattern.DOTALL).matcher(content); while (matcher.find()) { if (matcher.groupCount() >= 1) { int currentline = context.startLine() + countNewLinesUpTo(content, matcher.start()); + String linecontent = content.split("\\R")[currentline-context.startLine()]; int currentOffset = element.getStartTag().getEnd() + 1 + matcher.start(); - final String variableName = matcher.group(1); - if (!ignoreLines.contains(currentline)) { + String variableName = matcher.group(1); + Pattern allowLineExpressionPattern = null; + if ( !"".equals(allowLineExpression) ) { + //System.out.println(allowLineExpression.replaceAll("\\$\\{variable\\}","\\\\Q" + Matcher.quoteReplacement(variableName) + "\\\\E")); + allowLineExpressionPattern = Pattern.compile(allowLineExpression.replaceAll("\\$\\{variable\\}","\\\\Q" + Matcher.quoteReplacement(variableName) + "\\\\E"),Pattern.DOTALL); + } + if ( !ignoreLines.contains(currentline) + && (allowVariableExpressionPattern == null || !allowVariableExpressionPattern.matcher(variableName).find()) + && (allowLineExpressionPattern == null || !allowLineExpressionPattern.matcher(linecontent).find())) { + //System.out.println("linecontent:" + linecontent); context.addMessage("CFQUERYPARAM_REQ", variableName, currentline, currentOffset); } } @@ -63,18 +86,59 @@ public void element(final Element element, final Context context, final BugList * @param element the element object * @return the line numbers of any @@CFLintIgnore annotations. */ - private List determineIgnoreLines(final Element element) { + private List determineIgnoreLines(final String textContent, final int start ) { + final List ignoreLines = new ArrayList<>(); - for (Element comment : element.getChildElements()) { - if ("!---".equals(comment.getName()) && comment.toString().contains("@CFLintIgnore") && comment.toString().contains("CFQUERYPARAM_REQ")) { - int ignoreLine = comment.getSource().getRow(comment.getEnd()); - ignoreLines.add(ignoreLine); - ignoreLines.add(ignoreLine + 1); - ignoreLines.add(comment.getSource().getRow(comment.getBegin())); - } else { - ignoreLines.addAll(determineIgnoreLines(comment)); + int currentline = start; + String line = null; + List tmpIgnoreLines = new ArrayList<>(); + int match = 0; + + BufferedReader bufReader = new BufferedReader(new StringReader(textContent)); + + try { + while( (line=bufReader.readLine()) != null ) + { + if ( line.contains("!---") ) { + if (!tmpIgnoreLines.contains(currentline)) { + tmpIgnoreLines.add(currentline); + } + match = 1; + } + + if ( line.contains("@CFLintIgnore") && match > 0 ) { + if (!tmpIgnoreLines.contains(currentline)) { + tmpIgnoreLines.add(currentline); + } + match = 2; + } + + if ( line.contains("CFQUERYPARAM_REQ") && match > 1 ) { + if (!tmpIgnoreLines.contains(currentline)) { + tmpIgnoreLines.add(currentline); + } + match = 3; + } + + if ( line.contains("--->") && match > 2 ) { + if (!tmpIgnoreLines.contains(currentline)) { + tmpIgnoreLines.add(currentline); + } + if (!tmpIgnoreLines.contains(currentline+1)) { + tmpIgnoreLines.add(currentline+1); + } + ignoreLines.addAll(tmpIgnoreLines); + tmpIgnoreLines.clear(); + match = 0; + } + + currentline++; + } + } catch(Exception e) { + e.printStackTrace(); } + return ignoreLines; } diff --git a/src/main/java/com/cflint/plugins/core/ScriptTagChecker.java b/src/main/java/com/cflint/plugins/core/ScriptTagChecker.java index e4fcffe09..80a97e381 100644 --- a/src/main/java/com/cflint/plugins/core/ScriptTagChecker.java +++ b/src/main/java/com/cflint/plugins/core/ScriptTagChecker.java @@ -11,6 +11,12 @@ @Extension public class ScriptTagChecker extends CFLintScannerAdapter { + + /** + * @param element element + * @param context context + * @param bugs bugs + */ // rule: don't use inline javascript in cfm and cfc files @Override public void element(final Element element, final Context context, final BugList bugs) { diff --git a/src/main/java/com/cflint/plugins/core/SelectStarChecker.java b/src/main/java/com/cflint/plugins/core/SelectStarChecker.java index 4754ae633..dbdd948ec 100644 --- a/src/main/java/com/cflint/plugins/core/SelectStarChecker.java +++ b/src/main/java/com/cflint/plugins/core/SelectStarChecker.java @@ -12,6 +12,12 @@ public class SelectStarChecker extends CFLintScannerAdapter { private static final CharSequence selectStar = "select*"; + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(final Element element, final Context context, final BugList bugs) { final String tagName = element.getName(); diff --git a/src/main/java/com/cflint/plugins/core/SimpleComplexityChecker.java b/src/main/java/com/cflint/plugins/core/SimpleComplexityChecker.java index 0b52578f4..0ad13bf6b 100644 --- a/src/main/java/com/cflint/plugins/core/SimpleComplexityChecker.java +++ b/src/main/java/com/cflint/plugins/core/SimpleComplexityChecker.java @@ -24,6 +24,11 @@ public class SimpleComplexityChecker extends CFLintScannerAdapter { private int functionLineNo = 1; private int functionOffset = 0; + + /** + * @param fileName fileName + * @param bugs bugs + */ @Override public void startFile(final String fileName, final BugList bugs) { complexity = 0; diff --git a/src/main/java/com/cflint/plugins/core/StructKeyChecker.java b/src/main/java/com/cflint/plugins/core/StructKeyChecker.java index d04704743..a2a03cdcc 100644 --- a/src/main/java/com/cflint/plugins/core/StructKeyChecker.java +++ b/src/main/java/com/cflint/plugins/core/StructKeyChecker.java @@ -14,6 +14,12 @@ public class StructKeyChecker extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { diff --git a/src/main/java/com/cflint/plugins/core/TooManyArgumentsChecker.java b/src/main/java/com/cflint/plugins/core/TooManyArgumentsChecker.java index ce13befd4..e9c77b643 100644 --- a/src/main/java/com/cflint/plugins/core/TooManyArgumentsChecker.java +++ b/src/main/java/com/cflint/plugins/core/TooManyArgumentsChecker.java @@ -16,6 +16,12 @@ public class TooManyArgumentsChecker extends CFLintScannerAdapter { protected int functionLine = 0; protected int functionOffset = 0; + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFFuncDeclStatement) { diff --git a/src/main/java/com/cflint/plugins/core/TooManyFunctionsChecker.java b/src/main/java/com/cflint/plugins/core/TooManyFunctionsChecker.java index 59322c2a5..daaeaae74 100644 --- a/src/main/java/com/cflint/plugins/core/TooManyFunctionsChecker.java +++ b/src/main/java/com/cflint/plugins/core/TooManyFunctionsChecker.java @@ -16,6 +16,12 @@ public class TooManyFunctionsChecker extends CFLintScannerAdapter { protected int functionCount = 0; + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFScriptStatement expression, final Context context, final BugList bugs) { if (expression instanceof CFFuncDeclStatement && !trivalFunction(context.getFunctionName())) { diff --git a/src/main/java/com/cflint/plugins/core/TypedQueryNew.java b/src/main/java/com/cflint/plugins/core/TypedQueryNew.java index 6dc6df5b4..b56e99074 100644 --- a/src/main/java/com/cflint/plugins/core/TypedQueryNew.java +++ b/src/main/java/com/cflint/plugins/core/TypedQueryNew.java @@ -9,6 +9,12 @@ public class TypedQueryNew extends CFLintScannerAdapter { + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (expression instanceof CFFunctionExpression) { diff --git a/src/main/java/com/cflint/plugins/core/UnusedArgumentChecker.java b/src/main/java/com/cflint/plugins/core/UnusedArgumentChecker.java index d5a28877b..0f4861dd9 100644 --- a/src/main/java/com/cflint/plugins/core/UnusedArgumentChecker.java +++ b/src/main/java/com/cflint/plugins/core/UnusedArgumentChecker.java @@ -35,6 +35,12 @@ static class ArgInfo{ String casedName; } + + /** + * @param element element + * @param context context + * @param bugs bugs + */ @Override public void element(final Element element, final Context context, final BugList bugs) { if (element.getName().equals(CF.CFARGUMENT)) { diff --git a/src/main/java/com/cflint/plugins/core/UnusedLocalVarChecker.java b/src/main/java/com/cflint/plugins/core/UnusedLocalVarChecker.java index 5b1c2ba3a..22ab5bc1f 100644 --- a/src/main/java/com/cflint/plugins/core/UnusedLocalVarChecker.java +++ b/src/main/java/com/cflint/plugins/core/UnusedLocalVarChecker.java @@ -21,6 +21,12 @@ public class UnusedLocalVarChecker extends CFLintScannerAdapter { // LinkedHashMap is ordered. protected Map localVariables = new LinkedHashMap<>(); + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (expression instanceof CFFullVarExpression) { diff --git a/src/main/java/com/cflint/plugins/core/ValidName.java b/src/main/java/com/cflint/plugins/core/ValidName.java index 1b76cf476..04248cbda 100644 --- a/src/main/java/com/cflint/plugins/core/ValidName.java +++ b/src/main/java/com/cflint/plugins/core/ValidName.java @@ -119,6 +119,7 @@ public ValidName(final int minLength, final int maxLength, final int maxWords) { * Is a name valid?. * * @param name name of variable. + * @param caseType equalsIgnoreCase case type * @return true if name is valid or false if it is not. */ public boolean isInvalid(final String name,final String caseType) { @@ -134,6 +135,7 @@ public boolean isInvalid(final String name,final String caseType) { * Is a component name valid?. * * @param name name of variable. + * @param caseType equalsIgnoreCase case type * @return true if name is valid or false if it is not. */ public boolean isInvalidComponent(final String name,final String caseType) { @@ -394,12 +396,16 @@ public void setSuffixesToAvoid(final String[] suffixesToAvoid) { /** * Set the required prefixes. * - * @param prefixes + * @param prefixes prefix list */ public void setRequiredPrefixList(final String[] prefixes) { this.requiredPrefixes = prefixes; } + + /** + * @param minLength minLength + */ public void setMinLength(int minLength) { this.minLength = minLength; } diff --git a/src/main/java/com/cflint/plugins/core/VarScoper.java b/src/main/java/com/cflint/plugins/core/VarScoper.java index 4ec3862e1..8b0c3ff42 100644 --- a/src/main/java/com/cflint/plugins/core/VarScoper.java +++ b/src/main/java/com/cflint/plugins/core/VarScoper.java @@ -32,6 +32,12 @@ public class VarScoper extends CFLintScannerAdapter { private final Collection scopes = Arrays.asList(CF.APPLICATION, CF.CGI, CF.COOKIE, CF.FORM, CF.REQUEST, CF.SERVER, CF.SESSION, CF.URL, CF.CFTHREAD); + + /** + * @param expression expression + * @param context context + * @param bugs bugs + */ @Override public void expression(final CFExpression expression, final Context context, final BugList bugs) { if (expression instanceof CFIdentifier) { diff --git a/src/main/java/com/cflint/plugins/core/VariableNameChecker.java b/src/main/java/com/cflint/plugins/core/VariableNameChecker.java index 9f1cb93b1..9d2f36409 100644 --- a/src/main/java/com/cflint/plugins/core/VariableNameChecker.java +++ b/src/main/java/com/cflint/plugins/core/VariableNameChecker.java @@ -40,6 +40,15 @@ public class VariableNameChecker extends CFLintScannerAdapter { private static final List DEFAULT_EXCLUSIONS = Collections.singletonList("rc"); private static final String PARAM_EXCLUSION_LIST = "ExclusionList"; + + /** + * @param element element + * @param context context + * @param bugs bugs + * @param begLine begLine + * @param offset offset + * @param name name + */ //private final List exclusions = new ArrayList<>(); private void checkCFName(final Element element, final Context context, final BugList bugs, final int begLine, int offset, final String name) { diff --git a/src/main/java/com/cflint/plugins/exceptions/DefaultCFLintExceptionListener.java b/src/main/java/com/cflint/plugins/exceptions/DefaultCFLintExceptionListener.java index 924b61207..b2afe974a 100644 --- a/src/main/java/com/cflint/plugins/exceptions/DefaultCFLintExceptionListener.java +++ b/src/main/java/com/cflint/plugins/exceptions/DefaultCFLintExceptionListener.java @@ -18,6 +18,16 @@ public DefaultCFLintExceptionListener(final BugList bugs) { this.bugs = bugs; } + + /** + * @param exception exception + * @param messageCode messageCode + * @param filename filename + * @param line line + * @param column column + * @param functionName functionName + * @param expression expression + */ @Override public void exceptionOccurred(final Throwable exception, final String messageCode, final String filename, final Integer line, final Integer column, final String functionName, final String expression) { diff --git a/src/main/java/com/cflint/tools/AllowedExtensionsLoader.java b/src/main/java/com/cflint/tools/AllowedExtensionsLoader.java index 164410d44..dbaa673ec 100644 --- a/src/main/java/com/cflint/tools/AllowedExtensionsLoader.java +++ b/src/main/java/com/cflint/tools/AllowedExtensionsLoader.java @@ -14,6 +14,11 @@ private AllowedExtensionsLoader() { throw new IllegalStateException("AllowedExtensionsLoader utility class"); } + + /** + * @param resourceBundleName resourceBundleName + * @return List + */ public static List init(final String resourceBundleName) { List allowedExtensions = new ArrayList<>(); try { diff --git a/src/main/java/com/cflint/tools/CFLintDoc.java b/src/main/java/com/cflint/tools/CFLintDoc.java index b910cbf2c..57baf0c00 100644 --- a/src/main/java/com/cflint/tools/CFLintDoc.java +++ b/src/main/java/com/cflint/tools/CFLintDoc.java @@ -15,6 +15,11 @@ public class CFLintDoc { + + /** + * @param pluginInfo pluginInfo + * @param print print + */ public static void generateRuleGroup(final CFLintPluginInfo pluginInfo, final PrintWriter print){ final Map allCodes = new LinkedHashMap<>(); for (final PluginInfoRule rule : pluginInfo.getRules()) { diff --git a/src/main/java/com/cflint/tools/CFLintFilter.java b/src/main/java/com/cflint/tools/CFLintFilter.java index 2d4793907..f7ceb8fdc 100644 --- a/src/main/java/com/cflint/tools/CFLintFilter.java +++ b/src/main/java/com/cflint/tools/CFLintFilter.java @@ -38,6 +38,10 @@ private CFLintFilter(final ArrayList> data) { this.data = data; } + + /** + * @param filter filter + */ @Deprecated public void addFilter(final Map filter) { data.add(filter); diff --git a/src/main/java/com/cflint/tools/CFMLTagInfo.java b/src/main/java/com/cflint/tools/CFMLTagInfo.java index 32fd2f681..7a68b827f 100644 --- a/src/main/java/com/cflint/tools/CFMLTagInfo.java +++ b/src/main/java/com/cflint/tools/CFMLTagInfo.java @@ -15,6 +15,11 @@ public CFMLTagInfo(final SyntaxDictionary dictionary) { this.dictionary = dictionary; } + + /** + * @param elementName elementName + * @return boolean + */ public boolean isTag(String elementName){ final Tag tag = dictionary.getTag(elementName.toLowerCase()); return tag != null; diff --git a/src/main/java/com/cflint/tools/CFTool.java b/src/main/java/com/cflint/tools/CFTool.java index a7e32313c..df2390be6 100644 --- a/src/main/java/com/cflint/tools/CFTool.java +++ b/src/main/java/com/cflint/tools/CFTool.java @@ -17,6 +17,12 @@ private CFTool() { throw new IllegalStateException("CFTool utility class"); } + + /** + * @param elem elem + * @param tagName tagName + * @return Element + */ public static Element getNamedParent(final Element elem, final String tagName) { Element parentElem = elem.getParentElement(); while (parentElem != null && !parentElem.getName().equals(tagName)) { diff --git a/src/main/java/com/cflint/tools/CommentReformatting.java b/src/main/java/com/cflint/tools/CommentReformatting.java index 4b22a1c79..a73eea75d 100644 --- a/src/main/java/com/cflint/tools/CommentReformatting.java +++ b/src/main/java/com/cflint/tools/CommentReformatting.java @@ -11,6 +11,11 @@ private CommentReformatting() { throw new IllegalStateException("CommentReformatting utility class"); } + + /** + * @param value value + * @return String + */ public static String wrap(final String value) { Stack stack = new Stack<>(); StringBuilder sb = new StringBuilder(value); diff --git a/src/main/java/com/cflint/tools/FileUtil.java b/src/main/java/com/cflint/tools/FileUtil.java index 779248c0a..e5d66b27a 100644 --- a/src/main/java/com/cflint/tools/FileUtil.java +++ b/src/main/java/com/cflint/tools/FileUtil.java @@ -16,6 +16,11 @@ public class FileUtil { private static final String DEFAULT_ENCODING = "UTF-8"; private static final int BUF_SIZE = 8192; + + /** + * @param file file + * @return String + */ public static String loadFile(final File file) { FileInputStream fis = null; try { diff --git a/src/main/java/com/cflint/tools/ObjectEquals.java b/src/main/java/com/cflint/tools/ObjectEquals.java index 315d2ee9b..ea699b7bc 100644 --- a/src/main/java/com/cflint/tools/ObjectEquals.java +++ b/src/main/java/com/cflint/tools/ObjectEquals.java @@ -6,6 +6,12 @@ private ObjectEquals() { throw new IllegalStateException("ObjectEquals utility class"); } + + /** + * @param a a + * @param b b + * @return boolean + */ public static boolean equals(final Object a, final Object b) { if (a == null) { return b == null; diff --git a/src/main/java/com/cflint/tools/PrecedingCommentReader.java b/src/main/java/com/cflint/tools/PrecedingCommentReader.java index b9a2fdc2d..78f7b3993 100644 --- a/src/main/java/com/cflint/tools/PrecedingCommentReader.java +++ b/src/main/java/com/cflint/tools/PrecedingCommentReader.java @@ -15,6 +15,12 @@ private PrecedingCommentReader() { throw new IllegalStateException("PrecedingCommentReader utility class"); } + + /** + * @param context context + * @param token token + * @return String + */ public static String getMultiLine(final Context context, final Token token) { Iterable tokens = context.beforeTokens(token); for (Token currentTok : tokens) { diff --git a/src/main/java/com/cflint/tools/ScanningProgressMonitorLookAhead.java b/src/main/java/com/cflint/tools/ScanningProgressMonitorLookAhead.java index 7275e3edd..232a03f72 100644 --- a/src/main/java/com/cflint/tools/ScanningProgressMonitorLookAhead.java +++ b/src/main/java/com/cflint/tools/ScanningProgressMonitorLookAhead.java @@ -13,6 +13,13 @@ public class ScanningProgressMonitorLookAhead { private final File folder; private List allowedExtensions; + + /** + * @param cflint cflint + * @param folderName folderName + * @param startNewThread startNewThread + * @return ScanningProgressMonitorLookAhead + */ public static ScanningProgressMonitorLookAhead createInstance(CFLint cflint, final String folderName, boolean startNewThread) { ScanningProgressMonitorLookAhead lookAhead = new ScanningProgressMonitorLookAhead(folderName, startNewThread); diff --git a/src/main/java/com/cflint/xml/stax/DefaultCFlintResultMarshaller.java b/src/main/java/com/cflint/xml/stax/DefaultCFlintResultMarshaller.java index 076a4180e..cb61b7cd2 100644 --- a/src/main/java/com/cflint/xml/stax/DefaultCFlintResultMarshaller.java +++ b/src/main/java/com/cflint/xml/stax/DefaultCFlintResultMarshaller.java @@ -18,6 +18,13 @@ */ public class DefaultCFlintResultMarshaller implements CFLintResultMarshaller { + + /** + * @param bugList bugList + * @param writer writer + * @param stats stats + * @throws MarshallerException MarshallerException + */ @Override public void output(final BugList bugList, final Writer writer, final CFLintStats stats) throws MarshallerException { diff --git a/src/main/java/com/cflint/xml/stax/FindBugsCFLintResultMarshaller.java b/src/main/java/com/cflint/xml/stax/FindBugsCFLintResultMarshaller.java index 2710cd7ba..cb4456bbe 100644 --- a/src/main/java/com/cflint/xml/stax/FindBugsCFLintResultMarshaller.java +++ b/src/main/java/com/cflint/xml/stax/FindBugsCFLintResultMarshaller.java @@ -3,6 +3,9 @@ import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; @@ -17,6 +20,13 @@ public class FindBugsCFLintResultMarshaller implements CFLintResultMarshaller { + + /** + * @param bugList bugList + * @param writer writer + * @param stats stats + * @throws MarshallerException MarshallerException + */ @Override public void output(final BugList bugList, final Writer writer, final CFLintStats stats) throws MarshallerException { try { @@ -34,4 +44,8 @@ public void output(final BugList bugList, final Writer writer, final CFLintStats throw new MarshallerException(e); } } + + public static String formatDate(String dateString) { + return new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH).format(new Date(Integer.parseInt(dateString))); + } } diff --git a/src/main/resources/cflint.definition.json b/src/main/resources/cflint.definition.json index 2277e16f0..800cf6dfa 100644 --- a/src/main/resources/cflint.definition.json +++ b/src/main/resources/cflint.definition.json @@ -27,6 +27,17 @@ ], "parameter": [] }, + { + "name": "ImplicitScopeChecker", + "message": [ + { + "code": "IMPLICIT_SCOPE", + "messageText": "Variable ${variable} referenced maybe implicit scope.", + "severity": "INFO" + } + ], + "parameter": [] + }, { "name": "CFSwitchDefaultChecker", "message": [ @@ -60,7 +71,7 @@ ], "parameter": [] }, - { + { "name": "OutputParmMissing", "message": [ { @@ -71,6 +82,17 @@ ], "parameter": [] }, + { + "name": "AddTokenMissing", + "message": [ + { + "code": "ADDTOKEN_ATTR", + "messageText": "<${tag} url=\"${variable}\"> should have @addtoken='false'", + "severity": "INFO" + } + ], + "parameter": [] + }, { "name": "QueryParamChecker", "message": [ @@ -85,7 +107,16 @@ "severity": "WARNING" } ], - "parameter": [] + "parameter": [ + { + "name": "allowVariableExpression", + "value": "" + }, + { + "name": "allowLineExpression", + "value": "" + } + ] }, { "name": "TypedQueryNew", @@ -234,6 +265,125 @@ } ] }, + { + "name": "CFInvokeChecker", + "className": "CFXTagChecker", + "message": [ + { + "code": "AVOID_USING_CFINVOKE_TAG", + "messageText": "Avoid using <${tagName}> tags. Use factory or new Object instead.", + "severity": "WARNING" + } + ], + "parameter": [ + { + "name": "tagName", + "value": "cfinvoke" + } + ] + }, + { + "name": "CFFormChecker", + "className": "CFXTagChecker", + "message": [ + { + "code": "AVOID_USING_CFFORM_TAG", + "messageText": "Avoid using <${tagName}> tags. Use html tags instead.", + "severity": "WARNING" + } + ], + "parameter": [ + { + "name": "tagName", + "value": "cfform" + } + ] + }, + { + "name": "CFInputChecker", + "className": "CFXTagChecker", + "message": [ + { + "code": "AVOID_USING_CFINPUT_TAG", + "messageText": "Avoid using <${tagName}> tags. Use html tags instead.", + "severity": "WARNING" + } + ], + "parameter": [ + { + "name": "tagName", + "value": "cfinput" + } + ] + }, + { + "name": "CFFileChecker", + "className": "CFXTagChecker", + "message": [ + { + "code": "AVOID_USING_CFFILE_TAG", + "messageText": "Avoid using <${tagName}> tags. Use abstraction functions instead.", + "severity": "WARNING" + } + ], + "parameter": [ + { + "name": "tagName", + "value": "cffile" + } + ] + }, + { + "name": "CFDirectoryChecker", + "className": "CFXTagChecker", + "message": [ + { + "code": "AVOID_USING_CFDIRECTORY_TAG", + "messageText": "Avoid using <${tagName}> tags. Use abstraction functions instead.", + "severity": "WARNING" + } + ], + "parameter": [ + { + "name": "tagName", + "value": "cfdirectory" + } + ] + }, + { + "name": "CFCookieChecker", + "className": "CFXTagChecker", + "message": [ + { + "code": "AVOID_USING_CFCOOKIE_TAG", + "messageText": "Avoid using <${tagName}> tags. Use abstraction functions instead.", + "severity": "WARNING" + } + ], + "parameter": [ + { + "name": "tagName", + "value": "cfcookie" + } + ] + }, + { + "name": "CFHttpChecker", + "className": "CFXTagChecker", + "message": [ + { + "code": "AVOID_USING_CFHTTP_TAG", + "messageText": "Avoid using <${tagName}> tags. Use abstraction functions instead.", + "severity": "WARNING" + } + ], + "parameter": [ + { + "name": "tagName", + "value": "cfhttp" + } + ] + }, { "name": "CFIncludeChecker", "className": "CFXTagChecker", @@ -477,6 +627,40 @@ } ] }, + { + "name": "EvaluateChecker", + "className": "FunctionXChecker", + "message": [ + { + "code": "AVOID_USING_EVALUATE", + "messageText": "Avoid using the ${functionName} function in production code.", + "severity": "INFO" + } + ], + "parameter": [ + { + "name": "functionName", + "value": "evaluate" + } + ] + }, + { + "name": "IsDefinedChecker", + "className": "FunctionXChecker", + "message": [ + { + "code": "AVOID_USING_ISDEFINED", + "messageText": "Avoid using the ${functionName} function in production code.", + "severity": "INFO" + } + ], + "parameter": [ + { + "name": "functionName", + "value": "IsDefined" + } + ] + }, { "name": "FunctionCollisionChecker", "className": "FunctionCollisionChecker", @@ -495,7 +679,7 @@ { "code": "AVOID_USING_ARRAYNEW", "severity": "INFO", - "messageText": "Use implict array construction instead (= [])." + "messageText": "Use implicit array construction instead (= [])." } ], "parameter": [] @@ -1038,6 +1222,9 @@ "AVOID_USING_CFINSERT_TAG", "AVOID_USING_CFMODULE_TAG", "AVOID_USING_CFUPDATE_TAG", + "AVOID_USING_CFINVOKE_TAG", + "AVOID_USING_CFFORM_TAG", + "AVOID_USING_CFINPUT_TAG", "AVOID_USING_WRITEDUMP", "GLOBAL_LITERAL_VALUE_USED_TOO_OFTEN", "GLOBAL_VAR", @@ -1053,7 +1240,12 @@ "name": "Security", "message": [ "CFQUERYPARAM_REQ", - "QUERYPARAM_REQ" + "QUERYPARAM_REQ", + "ADDTOKEN_ATTR", + "AVOID_USING_CFFILE_TAG", + "AVOID_USING_CFDIRECTORY_TAG", + "AVOID_USING_CFCOOKIE_TAG", + "AVOID_USING_CFHTTP_TAG" ] }, { diff --git a/src/main/resources/cflint.description.txt b/src/main/resources/cflint.description.txt index cbcdd7c7d..b092cc12a 100644 --- a/src/main/resources/cflint.description.txt +++ b/src/main/resources/cflint.description.txt @@ -1,10 +1,12 @@ ARG_DEFAULT_MISSING:Optional argument is missing a default value. ARG_VAR_CONFLICT:Variable declared in both local and argument scopes. ARG_VAR_MIXED:Variable referenced in local and argument scopes. +IMPLICIT_SCOPE:Variable referenced maybe implicit scope. NO_DEFAULT_INSIDE_SWITCH:Missing default switch statement. GLOBAL_VAR:Global variable exists. NESTED_CFOUTPUT:Nested cfoutput with cfquery tag. OUTPUT_ATTR:Tag should have output='false'. +ADDTOKEN_ATTR:Tag should have addtoken='false'. QUERYPARAM_REQ:Use query parameters for variables in sql statements. CFQUERYPARAM_REQ:cfquery should use . QUERYNEW_DATATYPE:QueryNew statement should specify data types. @@ -16,6 +18,13 @@ AVOID_USING_ABORT:Avoid use of abort statements. AVOID_USING_CFINSERT_TAG:Avoid use of cfinsert tags. AVOID_USING_CFMODULE_TAG:Avoid use of cfmodule tags. AVOID_USING_CFUPDATE_TAG:Avoid use of cfupdate tags. +AVOID_USING_CFFORM_TAG:Avoid use of CFFORM tags +AVOID_USING_CFINPUT_TAG:Avoid use of CFINPUT tags +AVOID_USING_CFINVOKE_TAG:Avoid use of CFINVOKE tags +AVOID_USING_CFFILE_TAG:Avoid use of CFFILE tags +AVOID_USING_CFDIRECTORY_TAG:Avoid use of CFDIRECTORY tags +AVOID_USING_CFCOOKIE_TAG:Avoid use of CFCOOKIE tags +AVOID_USING_CFHTTP_TAG:Avoid use of CFHTTP tags AVOID_USING_CFINCLUDE_TAG:Avoid use of cfinclude tags. COMPONENT_HINT_MISSING:Component is missing a hint. FUNCTION_HINT_MISSING:Function is missing a hint. @@ -32,6 +41,8 @@ FUNCTION_TOO_COMPLEX:Function is too complex. AVOID_USING_WRITEDUMP:Avoid use of writeDump statements. AVOID_USING_STRUCTNEW:Avoid use of structNew statements. Use {} instead. AVOID_USING_ISDEBUGMODE:Avoid use of isDebugMode statements. +AVOID_USING_ISDEFINED:Avoid use of isdefined statements. +AVOID_USING_EVALUATE:Avoid use of evaluate statements. AVOID_USING_ARRAYNEW:Avoid use of arrayNew statements. Use [] instead. COMPLEX_BOOLEAN_CHECK:Complex boolean expression. EXPLICIT_BOOLEAN_CHECK:Checking boolean expression explicitly. diff --git a/src/main/resources/findbugs/cflint-to-findbugs.xsl b/src/main/resources/findbugs/cflint-to-findbugs.xsl index ac6ed735e..cc4914f43 100644 --- a/src/main/resources/findbugs/cflint-to-findbugs.xsl +++ b/src/main/resources/findbugs/cflint-to-findbugs.xsl @@ -2,8 +2,8 @@ - - + @@ -34,7 +34,7 @@ - + @@ -110,7 +110,7 @@ Nested <cfquery/> tags, the outer tag has an @query attribute, it should also specify the @group attribute. - + QueryNew should specify the datatypes of the columns. @@ -119,12 +119,18 @@ Variable referenced both as an unscoped (local) and an argument. + + Variable referenced maybe implicit scope. + Arguments that are not required should specify a default value (@default) Functions should specify @output="false" + + CFLocation should specify @addtoken="false" + @@ -142,11 +148,11 @@ 1 2 - 3 - 4 - 5 - 6 - 7 + 2 + 2 + 2 + 3 + 3 @@ -195,7 +201,7 @@ - + @@ -238,7 +244,7 @@ - + diff --git a/src/test/java/com/cflint/TestAbortChecker.java b/src/test/java/com/cflint/TestAbortChecker.java index 209571465..55e66335e 100644 --- a/src/test/java/com/cflint/TestAbortChecker.java +++ b/src/test/java/com/cflint/TestAbortChecker.java @@ -16,6 +16,10 @@ public class TestAbortChecker { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("AVOID_USING_ABORT"); diff --git a/src/test/java/com/cflint/TestArgumentNames.java b/src/test/java/com/cflint/TestArgumentNames.java index d55a7b4be..731c54478 100644 --- a/src/test/java/com/cflint/TestArgumentNames.java +++ b/src/test/java/com/cflint/TestArgumentNames.java @@ -17,6 +17,10 @@ public class TestArgumentNames { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("ARGUMENT_MISSING_NAME","ARGUMENT_INVALID_NAME","ARGUMENT_ALLCAPS_NAME","ARGUMENT_TOO_SHORT","ARGUMENT_TOO_LONG","ARGUMENT_TOO_WORDY","ARGUMENT_IS_TEMPORARY","ARGUMENT_HAS_PREFIX_OR_POSTFIX"); diff --git a/src/test/java/com/cflint/TestArrayNewChecker.java b/src/test/java/com/cflint/TestArrayNewChecker.java index ffe7aeafe..7b0dc2689 100644 --- a/src/test/java/com/cflint/TestArrayNewChecker.java +++ b/src/test/java/com/cflint/TestArrayNewChecker.java @@ -16,6 +16,10 @@ public class TestArrayNewChecker { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("AVOID_USING_ARRAYNEW"); @@ -32,7 +36,7 @@ public void testArrayNewInScript() throws CFLintScanException { assertEquals("AVOID_USING_ARRAYNEW", result.get(0).getMessageCode()); assertEquals(4, result.get(0).getLine()); assertEquals(Levels.INFO, result.get(0).getSeverity()); - assertEquals("Use implict array construction instead (= []).", result.get(0).getMessage()); + assertEquals("Use implicit array construction instead (= []).", result.get(0).getMessage()); } @Test @@ -53,7 +57,7 @@ public void testArrayNewInTag() throws CFLintScanException { assertEquals("AVOID_USING_ARRAYNEW", result.get(0).getMessageCode()); assertEquals(2, result.get(0).getLine()); assertEquals(Levels.INFO, result.get(0).getSeverity()); - assertEquals("Use implict array construction instead (= []).", result.get(0).getMessage()); + assertEquals("Use implicit array construction instead (= []).", result.get(0).getMessage()); } } diff --git a/src/test/java/com/cflint/TestBooleanExpressionChecker.java b/src/test/java/com/cflint/TestBooleanExpressionChecker.java index b342f7b89..39025230d 100644 --- a/src/test/java/com/cflint/TestBooleanExpressionChecker.java +++ b/src/test/java/com/cflint/TestBooleanExpressionChecker.java @@ -16,6 +16,10 @@ public class TestBooleanExpressionChecker { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("EXPLICIT_BOOLEAN_CHECK"); diff --git a/src/test/java/com/cflint/TestCFAbortChecker.java b/src/test/java/com/cflint/TestCFAbortChecker.java index acd5f56ae..2534f00c4 100644 --- a/src/test/java/com/cflint/TestCFAbortChecker.java +++ b/src/test/java/com/cflint/TestCFAbortChecker.java @@ -14,6 +14,10 @@ public class TestCFAbortChecker { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("AVOID_USING_CFABORT_TAG"); diff --git a/src/test/java/com/cflint/TestCFBugs.java b/src/test/java/com/cflint/TestCFBugs.java index 6f39308f5..cda1855eb 100644 --- a/src/test/java/com/cflint/TestCFBugs.java +++ b/src/test/java/com/cflint/TestCFBugs.java @@ -20,6 +20,11 @@ public class TestCFBugs { private CFLintAPI cfBugs; + + /** + * @throws IOException IOException + * @throws CFLintConfigurationException CFLintConfigurationException + */ @Before public void setUp() throws IOException, CFLintConfigurationException { final ConfigBuilder configBuilder = new ConfigBuilder().include("MISSING_VAR","GLOBAL_VAR","NESTED_CFOUTPUT","QUERYNEW_DATATYPE","MISSING_SEMI"); diff --git a/src/test/java/com/cflint/TestCFBugsFilter.java b/src/test/java/com/cflint/TestCFBugsFilter.java index 7ff53dd4d..f0c601c4d 100644 --- a/src/test/java/com/cflint/TestCFBugsFilter.java +++ b/src/test/java/com/cflint/TestCFBugsFilter.java @@ -11,6 +11,10 @@ public class TestCFBugsFilter { + + /** + * @throws IOException IOException + */ @Test public void testExclude1() throws IOException { BugInfo bugInfo = new BugInfo.BugInfoBuilder().setFunction("testf").setMessageCode("PARSE_ERROR").build(); diff --git a/src/test/java/com/cflint/TestCFBugsTagless.java b/src/test/java/com/cflint/TestCFBugsTagless.java index a82936f4d..9e0fe448d 100644 --- a/src/test/java/com/cflint/TestCFBugsTagless.java +++ b/src/test/java/com/cflint/TestCFBugsTagless.java @@ -18,6 +18,11 @@ public class TestCFBugsTagless { private CFLintAPI cfBugs; + + /** + * @throws IOException IOException + * @throws CFLintConfigurationException CFLintConfigurationException + */ @Before public void setUp() throws IOException, CFLintConfigurationException { final ConfigBuilder configBuilder = new ConfigBuilder().include("MISSING_VAR"); diff --git a/src/test/java/com/cflint/TestCFBugs_AddTokenDef.java b/src/test/java/com/cflint/TestCFBugs_AddTokenDef.java new file mode 100644 index 000000000..627152b76 --- /dev/null +++ b/src/test/java/com/cflint/TestCFBugs_AddTokenDef.java @@ -0,0 +1,51 @@ +package com.cflint; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.cflint.api.CFLintAPI; +import com.cflint.api.CFLintResult; +import com.cflint.config.ConfigBuilder; +import com.cflint.exception.CFLintScanException; + +public class TestCFBugs_AddTokenDef { + + private CFLintAPI cfBugs; + + + /** + * @throws Exception Exception + */ + @Before + public void setUp() throws Exception { + final ConfigBuilder configBuilder = new ConfigBuilder().include("ADDTOKEN_ATTR"); + cfBugs = new CFLintAPI(configBuilder.build()); + } + + @Test + public void testTokenDef() throws CFLintScanException { + final String cfcSrc = "\r\n" + "\r\n" + + " \r\n" + "\r\n" + + ""; + CFLintResult lintresult = cfBugs.scan(cfcSrc, "test"); + final List result = lintresult.getIssues().values().iterator().next(); + assertEquals(1, result.size()); + assertEquals("ADDTOKEN_ATTR", result.get(0).getMessageCode()); + assertEquals(3, result.get(0).getLine()); + assertEquals(" should have @addtoken='false'", result.get(0).getMessage()); + } + + @Test + public void test_OK() throws CFLintScanException { + final String cfcSrc = "\r\n" + "\r\n" + + " \r\n" + "\r\n" + + ""; + CFLintResult lintresult = cfBugs.scan(cfcSrc, "test"); + assertEquals(0, lintresult.getIssues().size()); + } + +} diff --git a/src/test/java/com/cflint/TestCFBugs_ArgsDef.java b/src/test/java/com/cflint/TestCFBugs_ArgsDef.java index 78798b3c5..746b7caf6 100644 --- a/src/test/java/com/cflint/TestCFBugs_ArgsDef.java +++ b/src/test/java/com/cflint/TestCFBugs_ArgsDef.java @@ -17,6 +17,10 @@ public class TestCFBugs_ArgsDef { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("ARG_DEFAULT_MISSING"); diff --git a/src/test/java/com/cflint/TestCFBugs_ArgsDefCond.java b/src/test/java/com/cflint/TestCFBugs_ArgsDefCond.java index 0fc94cb24..c41fc17da 100644 --- a/src/test/java/com/cflint/TestCFBugs_ArgsDefCond.java +++ b/src/test/java/com/cflint/TestCFBugs_ArgsDefCond.java @@ -18,6 +18,10 @@ public class TestCFBugs_ArgsDefCond { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("ARG_DEFAULT_MISSING"); diff --git a/src/test/java/com/cflint/TestCFBugs_ArgsHint.java b/src/test/java/com/cflint/TestCFBugs_ArgsHint.java index b68e27956..effce514e 100644 --- a/src/test/java/com/cflint/TestCFBugs_ArgsHint.java +++ b/src/test/java/com/cflint/TestCFBugs_ArgsHint.java @@ -17,6 +17,10 @@ public class TestCFBugs_ArgsHint { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("ARG_HINT_MISSING"); diff --git a/src/test/java/com/cflint/TestCFBugs_ArgsType.java b/src/test/java/com/cflint/TestCFBugs_ArgsType.java index 8cc0aa36b..118982aaa 100644 --- a/src/test/java/com/cflint/TestCFBugs_ArgsType.java +++ b/src/test/java/com/cflint/TestCFBugs_ArgsType.java @@ -16,6 +16,10 @@ public class TestCFBugs_ArgsType { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("ARG_TYPE_MISSING","ARG_TYPE_ANY"); diff --git a/src/test/java/com/cflint/TestCFBugs_ArgsUse.java b/src/test/java/com/cflint/TestCFBugs_ArgsUse.java index 7d2326b62..e765e5dfd 100644 --- a/src/test/java/com/cflint/TestCFBugs_ArgsUse.java +++ b/src/test/java/com/cflint/TestCFBugs_ArgsUse.java @@ -17,6 +17,10 @@ public class TestCFBugs_ArgsUse { StackHandler handler = null; private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("ARG_VAR_CONFLICT","ARG_VAR_MIXED"); diff --git a/src/test/java/com/cflint/TestCFBugs_Comments.java b/src/test/java/com/cflint/TestCFBugs_Comments.java index 47ba1cc30..cf2aefd64 100644 --- a/src/test/java/com/cflint/TestCFBugs_Comments.java +++ b/src/test/java/com/cflint/TestCFBugs_Comments.java @@ -17,6 +17,10 @@ public class TestCFBugs_Comments { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("ARG_DEFAULT_MISSING"); diff --git a/src/test/java/com/cflint/TestCFBugs_ComponentHint.java b/src/test/java/com/cflint/TestCFBugs_ComponentHint.java index ca19faa80..a62dc6f34 100644 --- a/src/test/java/com/cflint/TestCFBugs_ComponentHint.java +++ b/src/test/java/com/cflint/TestCFBugs_ComponentHint.java @@ -17,6 +17,10 @@ public class TestCFBugs_ComponentHint { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("COMPONENT_HINT_MISSING"); diff --git a/src/test/java/com/cflint/TestCFBugs_ComponentName.java b/src/test/java/com/cflint/TestCFBugs_ComponentName.java index 9edc74fd6..9f3a72691 100644 --- a/src/test/java/com/cflint/TestCFBugs_ComponentName.java +++ b/src/test/java/com/cflint/TestCFBugs_ComponentName.java @@ -17,6 +17,10 @@ public class TestCFBugs_ComponentName { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("USE_DISPLAY_NAME"); diff --git a/src/test/java/com/cflint/TestCFBugs_ComponentNames.java b/src/test/java/com/cflint/TestCFBugs_ComponentNames.java index 230bdd0d8..5e403c9c8 100644 --- a/src/test/java/com/cflint/TestCFBugs_ComponentNames.java +++ b/src/test/java/com/cflint/TestCFBugs_ComponentNames.java @@ -17,6 +17,10 @@ public class TestCFBugs_ComponentNames { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("COMPONENT_INVALID_NAME","COMPONENT_ALLCAPS_NAME","COMPONENT_TOO_SHORT","COMPONENT_TOO_LONG","COMPONENT_TOO_WORDY","COMPONENT_IS_TEMPORARY","COMPONENT_HAS_PREFIX_OR_POSTFIX"); diff --git a/src/test/java/com/cflint/TestCFBugs_FunctionHint.java b/src/test/java/com/cflint/TestCFBugs_FunctionHint.java index 3afe4393b..302fc25fc 100644 --- a/src/test/java/com/cflint/TestCFBugs_FunctionHint.java +++ b/src/test/java/com/cflint/TestCFBugs_FunctionHint.java @@ -17,6 +17,10 @@ public class TestCFBugs_FunctionHint { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("FUNCTION_HINT_MISSING"); diff --git a/src/test/java/com/cflint/TestCFBugs_FunctionType.java b/src/test/java/com/cflint/TestCFBugs_FunctionType.java index f747daf9c..5366faaa1 100644 --- a/src/test/java/com/cflint/TestCFBugs_FunctionType.java +++ b/src/test/java/com/cflint/TestCFBugs_FunctionType.java @@ -16,6 +16,10 @@ public class TestCFBugs_FunctionType { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("FUNCTION_TYPE_MISSING","FUNCTION_TYPE_ANY"); diff --git a/src/test/java/com/cflint/TestCFBugs_GLobalVarChecker.java b/src/test/java/com/cflint/TestCFBugs_GLobalVarChecker.java index 1739a6742..f9f9172cb 100644 --- a/src/test/java/com/cflint/TestCFBugs_GLobalVarChecker.java +++ b/src/test/java/com/cflint/TestCFBugs_GLobalVarChecker.java @@ -16,6 +16,10 @@ public class TestCFBugs_GLobalVarChecker { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("GLOBAL_VAR"); diff --git a/src/test/java/com/cflint/TestCFBugs_ImplicitScope.java b/src/test/java/com/cflint/TestCFBugs_ImplicitScope.java new file mode 100644 index 000000000..14e608f60 --- /dev/null +++ b/src/test/java/com/cflint/TestCFBugs_ImplicitScope.java @@ -0,0 +1,70 @@ +package com.cflint; + +import static org.junit.Assert.assertEquals; + +import java.util.List; +import org.junit.Before; +import org.junit.Test; + +import com.cflint.api.CFLintAPI; +import com.cflint.api.CFLintResult; +import com.cflint.config.ConfigBuilder; +import com.cflint.exception.CFLintScanException; + +public class TestCFBugs_ImplicitScope { + + private CFLintAPI cfBugs; + + + /** + * @throws Exception Exception + */ + @Before + public void setUp() throws Exception { + final ConfigBuilder configBuilder = new ConfigBuilder().include("IMPLICIT_SCOPE"); + cfBugs = new CFLintAPI(configBuilder.build()); + } + + @Test + public void testImplicitScope() throws CFLintScanException { + final String cfcSrc = "\r\n" + + "\r\n" + + " \r\n" + + "\r\n" + + "#test3#\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + // + "\r\n" + // + "\r\n" + // + "\r\n" + // + "\r\n" + + "\r\n" + + ""; + CFLintResult lintresult = cfBugs.scan(cfcSrc, "test.cfc"); + final List result = lintresult.getIssues().values().iterator().next(); + assertEquals(4, result.size()); + assertEquals("IMPLICIT_SCOPE", result.get(0).getMessageCode()); + assertEquals("IMPLICIT_SCOPE", result.get(1).getMessageCode()); + assertEquals("IMPLICIT_SCOPE", result.get(2).getMessageCode()); + assertEquals("IMPLICIT_SCOPE", result.get(3).getMessageCode()); + assertEquals(4, result.get(0).getLine()); + assertEquals(5, result.get(1).getLine()); + assertEquals(10, result.get(2).getLine()); + assertEquals(11, result.get(3).getLine()); + } + + @Test + public void testImplicitScopeCFM() throws CFLintScanException { + final String cfmSrc = "\r\n"; + CFLintResult lintresult = cfBugs.scan(cfmSrc, "test.cfm"); + final List result = lintresult.getIssues().values().iterator().next(); + assertEquals(1, result.size()); + assertEquals("IMPLICIT_SCOPE", result.get(0).getMessageCode()); + assertEquals(2, result.get(0).getLine()); + } + +} diff --git a/src/test/java/com/cflint/TestCFBugs_MethodNames.java b/src/test/java/com/cflint/TestCFBugs_MethodNames.java index 4ccc64172..3e38e1f9b 100644 --- a/src/test/java/com/cflint/TestCFBugs_MethodNames.java +++ b/src/test/java/com/cflint/TestCFBugs_MethodNames.java @@ -17,6 +17,10 @@ public class TestCFBugs_MethodNames { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("METHOD_INVALID_NAME","METHOD_ALLCAPS_NAME","METHOD_TOO_SHORT","METHOD_TOO_LONG","METHOD_TOO_WORDY","METHOD_IS_TEMPORARY","METHOD_HAS_PREFIX_OR_POSTFIX"); diff --git a/src/test/java/com/cflint/TestCFBugs_OutputDef.java b/src/test/java/com/cflint/TestCFBugs_OutputDef.java index 0bc8c0811..ec44e1397 100644 --- a/src/test/java/com/cflint/TestCFBugs_OutputDef.java +++ b/src/test/java/com/cflint/TestCFBugs_OutputDef.java @@ -16,6 +16,10 @@ public class TestCFBugs_OutputDef { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("OUTPUT_ATTR"); diff --git a/src/test/java/com/cflint/TestCFBugs_ParseError.java b/src/test/java/com/cflint/TestCFBugs_ParseError.java index 372616bdc..42ac6be6e 100644 --- a/src/test/java/com/cflint/TestCFBugs_ParseError.java +++ b/src/test/java/com/cflint/TestCFBugs_ParseError.java @@ -17,6 +17,10 @@ public class TestCFBugs_ParseError { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("PARSE_ERROR"); diff --git a/src/test/java/com/cflint/TestCFBugs_QueryParams.java b/src/test/java/com/cflint/TestCFBugs_QueryParams.java index db1d64240..c22cbdeb4 100644 --- a/src/test/java/com/cflint/TestCFBugs_QueryParams.java +++ b/src/test/java/com/cflint/TestCFBugs_QueryParams.java @@ -17,6 +17,10 @@ public class TestCFBugs_QueryParams { private CFLintAPI cfBugs; + + /** + * @throws Exception Exception + */ @Before public void setUp() throws Exception { final ConfigBuilder configBuilder = new ConfigBuilder().include("QUERYPARAM_REQ","CFQUERYPARAM_REQ"); @@ -138,6 +142,9 @@ public void testCFScript_QueryParams_ignore_offset() throws CFLintScanException " ON C.aID = A.aID\n" + " AND C.bar = #magicVal# \n" + + " \n" + + " #delim# C.bar = \n" + " WHERE \n" + "