SonarScanner NullPointerException on python scripts with invalid binary characters

We have a python script that we use to test cases where files have invalid binary characters.
Unfortunately the scanner throws an error while parsing it. While this is not ideal code, the python interpreter is working fine so the issue is with the scanner.

[2024-04-08T23:03:23.941Z] ERROR: Parse error at line 781 column 77:
[2024-04-08T23:03:23.941Z] 
[2024-04-08T23:03:23.941Z]   777: )
[2024-04-08T23:03:23.941Z]   778:             except FileNotFoundError:
[2024-04-08T23:03:23.941Z]   779:                 pass
[2024-04-08T23:03:23.941Z]   780:             else:
[2024-04-08T23:03:23.941Z]   -->          ends_in_ffff_file = mount / f'{ENDS_IN_FFFF_FILE_PREFIX}-{mount.name ?'
... snip ...
WARN: Unable to analyze file: example.py
java.lang.NullPointerException: Cannot invoke "org.sonar.plugins.python.api.tree.FileInput.statements()" because "fileInput" is null
at org.sonar.plugins.python.api.tree.BaseTreeVisitor.visitFileInput(BaseTreeVisitor.java:47)
at com.sonarsource.dbd.frontend.python.A.visitFileInput(na:1196)
at com.sonarsource.dbd.frontend.python.A.scanFile(na:2635)
at com.sonarsource.dbd.frontend.python.rules.A.scanFile(na:588)
at org.sonar.plugins.python.PythonScanner.scanFile(PythonScanner.java:133)
at org.sonar.plugins.python.Scanner.execute(Scanner.java:60)
at org.sonar.plugins.python.PythonSensor.execute(PythonSensor.java:130)
at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:62)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:75)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:48)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:66)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:48)
at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:64)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:192)
at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:188)
at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:159)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
at org.sonar.scanner.bootstrap.ScannerContainer.doAfterStart(ScannerContainer.java:397)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:125)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:57)
at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:51)
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)

Under most text editors the line would look like:

ends_in_ffff_file = mount / f'{ENDS_IN_FFFF_FILE_PREFIX}-{mount.name}'

But there is an invisible character just before the closing quote with a value of 0xffff.

We are updating the code to declare the binary value in a more explicit way which is better but sonar should not stop analyzing the entire file just for that:

ends_in_ffff_file = mount / f'{ENDS_IN_FFFF_FILE_PREFIX}-{mount.name}{0xffff}'

Note that we see the same null pointer exception thrown for strings that mix raw strings (python strings prefixed with r, backslashes, and line splitting. Again the code should not be written that way, but the entire file should not fail analysis either.

349:         windows_path = rf"C:\Program Files\Company Example\Company.\
350:         example\somthing-{randomizing_path}\\"
-->          other_path = rf"C:\Program Files\Company Example\Company.

Hello,

Thanks for the feedback, I have reproduced your issue successfully and created SONARPY-1792.

Have a nice day,
Ghislain