TypeScript analysis crash on complex regular expression

Hi,
I’ve encountered a problem when analyzing our project using SonarQube Enterprise Edition (version 10.2, build 77647).

The problem appears during Sensor JavaScript/TypeScript analysis and it is manifested by this error and stack trace in the analysis output:

ERROR: Failure during analysis, Node.js command to start the bridge was: C:\Program Files\nodejs\node.exe C:\repos\sonar-regex\.scannerwork\.sonartmp\bridge-bundle\package\bin\server 58338 127.0.0.1 C:\repos\sonar-regex\.scannerwork true false C:\repos\sonar-regex\.scannerwork\.sonartmp\bridge-bundle\package\custom-rules13249604902260132945\package
java.lang.IllegalArgumentException: Start pointer [line=1, lineOffset=138] should be before end pointer [line=1, lineOffset=138]
        at org.sonar.api.utils.Preconditions.checkArgument(Preconditions.java:43)
        at org.sonar.api.batch.fs.internal.DefaultInputFile.newRangeValidPointers(DefaultInputFile.java:383)
        at org.sonar.api.batch.fs.internal.DefaultInputFile.newRange(DefaultInputFile.java:324)
        at org.sonar.plugins.javascript.eslint.AnalysisProcessor.newSecondaryLocation(AnalysisProcessor.java:344)
        at org.sonar.plugins.javascript.eslint.AnalysisProcessor.lambda$saveIssue$0(AnalysisProcessor.java:283)
        at java.base/java.util.ArrayList.forEach(Unknown Source)
        at org.sonar.plugins.javascript.eslint.AnalysisProcessor.saveIssue(AnalysisProcessor.java:282)
        at org.sonar.plugins.javascript.eslint.AnalysisProcessor.saveIssues(AnalysisProcessor.java:179)
        at org.sonar.plugins.javascript.eslint.AnalysisProcessor.processResponse(AnalysisProcessor.java:112)
        at org.sonar.plugins.javascript.eslint.AnalysisWithProgram.analyze(AnalysisWithProgram.java:164)
        at org.sonar.plugins.javascript.eslint.AnalysisWithProgram.analyzeProgram(AnalysisWithProgram.java:133)
        at org.sonar.plugins.javascript.eslint.AnalysisWithProgram.analyzeFiles(AnalysisWithProgram.java:94)
        at org.sonar.plugins.javascript.eslint.JsTsSensor.analyzeFiles(JsTsSensor.java:124)
        at org.sonar.plugins.javascript.eslint.AbstractEslintSensor.execute(AbstractEslintSensor.java:74)
        at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61)
        at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82)
        at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
        at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
        at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:398)
        at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:394)
        at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:363)
        at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
        at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
        at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:139)
        at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
        at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
        at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:71)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:65)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at jdk.proxy1/jdk.proxy1.$Proxy0.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
        at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:126)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:81)
        at org.sonarsource.scanner.cli.Main.main(Main.java:62)

After this error, no more JavaScript/TypeScript files are analyzed.

The problem is reproducible by running SonarScanner CLI 5.0.1.3006 on this TypeScript code snippet:

const dateRegexp = new RegExp("^(?:31(\\/)(?:0?[13578]|1[02])\\1|(?:29|30)(\\/)(?:0?[1,3-9]|1[0-2])\\2)(?:1[6-9]|[2-9]\\d)?\\d{2}$|^29(\\/)0?2\\3(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:16|[2468][048]|[3579][26])00)$|^(?:0?[1-9]|1\\d|2[0-8])(\\/)(?:0?[1-9]|1[0-2])\\4(?:1[6-9]|[2-9]\\d)?\\d{2}$");

function isDate(str: string): boolean {
    return dateRegexp.test(str);
}

console.log("Is 01/02/2023 a date? " + isDate("01/02/2023"))

During my experiments I figured out that the issue can be fixed by converting regular expression from constructor invocation to regular expression literal but even using the constructor should not result in a crash of the analysis.

Thank you for the fix or any other assistance,
Petr

Hello @holubec.petr,

Welcome to our Sonar community and thank you for bringing this to our attention!

Rules analyzing regular expressions were producing unexpected runtime errors in certain situations like the one you shared, in particular when escaping was used within regular expressions. A fix was shipped into the new SonarQube released version, that is, SonarQube 10.3.

To double-check, I analyzed the code snippet you nicely shared with SonarQube 10.3 and the error is no longer there. All you need to do is update your SonarQube version.

Hope this helps,
Yassin

Hi,

thank you for the quick fix, I’ll update whenever it will be possible.

Petr