Skip to content

Commit

Permalink
Migrate WebViewJavaScriptSupportCheck to kotlin-analysis-api
Browse files Browse the repository at this point in the history
Co-authored-by: Marharyta Nedzelska <[email protected]>
Co-authored-by: Evgeny Mandrikov <[email protected]>
  • Loading branch information
Godin and leveretka committed Feb 2, 2025
1 parent bb013e2 commit 45718c5
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,7 @@ fun KtExpression?.isLocalVariable(): Boolean = withKaSession {
return mainReference.resolveToSymbol() is KaLocalVariableSymbol
}

@Deprecated("use kotlin-analysis-api instead")
fun KtExpression?.setterMatches(bindingContext: BindingContext, propertyName: String, matcher: FunMatcherImpl): Boolean = when (this) {
is KtNameReferenceExpression -> (getReferencedName() == propertyName) &&
(matcher.matches((bindingContext[BindingContext.REFERENCE_TARGET, this] as? PropertyDescriptor)?.unwrappedSetMethod))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,44 @@
*/
package org.sonarsource.kotlin.checks

import org.jetbrains.kotlin.analysis.api.resolution.KaCallableMemberCall
import org.jetbrains.kotlin.analysis.api.resolution.KaFunctionCall
import org.jetbrains.kotlin.analysis.api.resolution.singleCallOrNull
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtPsiUtil.deparenthesize
import org.jetbrains.kotlin.resolve.calls.util.getFirstArgumentExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.sonar.check.Rule
import org.sonarsource.kotlin.api.checks.CallAbstractCheck
import org.sonarsource.kotlin.api.checks.FunMatcher
import org.sonarsource.kotlin.api.checks.getFirstArgumentExpression
import org.sonarsource.kotlin.api.checks.predictRuntimeBooleanValue
import org.sonarsource.kotlin.api.checks.setterMatches
import org.sonarsource.kotlin.api.frontend.KotlinFileContext
import org.sonarsource.kotlin.api.visiting.withKaSession

private const val MESSAGE = "Make sure that enabling JavaScript support is safe here."
private val ANDROID_SET_JAVASCRIPT_ENABLED =
FunMatcher(definingSupertype = "android.webkit.WebSettings", name = "setJavaScriptEnabled") { withArguments("kotlin.Boolean") }

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6362")
class WebViewJavaScriptSupportCheck : CallAbstractCheck() {

override val functionsToVisit = listOf(ANDROID_SET_JAVASCRIPT_ENABLED)

override fun visitFunctionCall(callExpression: KtCallExpression, resolvedCall: ResolvedCall<*>, kotlinFileContext: KotlinFileContext) {
override fun visitFunctionCall(callExpression: KtCallExpression, resolvedCall: KaFunctionCall<*>, kotlinFileContext: KotlinFileContext) {
checkJavaScriptEnabledArgument(kotlinFileContext, resolvedCall.getFirstArgumentExpression())
}

override fun visitBinaryExpression(expression: KtBinaryExpression, ctx: KotlinFileContext) {
override fun visitBinaryExpression(expression: KtBinaryExpression, ctx: KotlinFileContext) = withKaSession {
if (expression.operationToken == KtTokens.EQ &&
deparenthesize(expression.left).setterMatches(ctx.bindingContext, "javaScriptEnabled", ANDROID_SET_JAVASCRIPT_ENABLED)
ANDROID_SET_JAVASCRIPT_ENABLED.matches(expression.resolveToCall()?.singleCallOrNull<KaCallableMemberCall<*, *>>())
) {
checkJavaScriptEnabledArgument(ctx, expression.right)
}
}

private fun checkJavaScriptEnabledArgument(ctx: KotlinFileContext, argument: KtExpression?) {
if (argument?.predictRuntimeBooleanValue(ctx.bindingContext) == true) {
private fun checkJavaScriptEnabledArgument(ctx: KotlinFileContext, argument: KtExpression?) = withKaSession {
if (argument?.predictRuntimeBooleanValue() == true) {
ctx.reportIssue(argument, MESSAGE)
}
}
Expand Down

0 comments on commit 45718c5

Please sign in to comment.