mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge branch 'main' into refacReDoS
This commit is contained in:
@@ -36,7 +36,7 @@ java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
|
||||
java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7,
|
||||
java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6,
|
||||
java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,,
|
||||
java.util,44,,458,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,36,422
|
||||
java.util,44,,461,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,36,425
|
||||
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,,
|
||||
javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57,
|
||||
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
|
||||
|
||||
|
@@ -15,9 +15,9 @@ Java framework & library support
|
||||
`Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25
|
||||
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,39,,6,,,,,
|
||||
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
|
||||
Java Standard Library,``java.*``,3,569,130,28,,,7,,,10
|
||||
Java Standard Library,``java.*``,3,572,130,28,,,7,,,10
|
||||
Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2
|
||||
`Spring <https://spring.io/>`_,``org.springframework.*``,29,476,101,,,,19,14,,29
|
||||
Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3
|
||||
Totals,,217,6430,1474,117,6,10,107,33,1,84
|
||||
Totals,,217,6433,1474,117,6,10,107,33,1,84
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.github.codeql.comments.CommentExtractor
|
||||
import com.github.codeql.utils.*
|
||||
import com.github.codeql.utils.versions.functionN
|
||||
import com.github.codeql.utils.versions.getIrStubFromDescriptor
|
||||
import com.github.codeql.utils.versions.isUnderscoreParameter
|
||||
import com.semmle.extractor.java.OdasaOutput
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
@@ -642,7 +643,7 @@ open class KotlinFileExtractor(
|
||||
if (extractTypeAccess) {
|
||||
extractTypeAccessRecursive(substitutedType, location, id, -1)
|
||||
}
|
||||
val syntheticParameterNames = (vp.parent as? IrFunction)?.let { hasSynthesizedParameterNames(it) } ?: true
|
||||
val syntheticParameterNames = isUnderscoreParameter(vp) || ((vp.parent as? IrFunction)?.let { hasSynthesizedParameterNames(it) } ?: true)
|
||||
return extractValueParameter(id, substitutedType, vp.name.asString(), location, parent, idx, useValueParameter(vp, parentSourceDeclaration), vp.isVararg, syntheticParameterNames)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) =
|
||||
try {
|
||||
DescriptorToSourceUtils.getSourceFromDescriptor(vp.descriptor)
|
||||
?.safeAs<KtParameter>()?.isSingleUnderscore == true
|
||||
} catch(e: NotImplementedError) {
|
||||
// Some kinds of descriptor throw in `getSourceFromDescriptor` as that method is not normally expected to
|
||||
// be applied to synthetic functions.
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) =
|
||||
try {
|
||||
DescriptorToSourceUtils.getSourceFromDescriptor(vp.descriptor)
|
||||
?.safeAs<KtParameter>()?.isSingleUnderscore == true
|
||||
} catch(e: NotImplementedError) {
|
||||
// Some kinds of descriptor throw in `getSourceFromDescriptor` as that method is not normally expected to
|
||||
// be applied to synthetic functions.
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) =
|
||||
try {
|
||||
DescriptorToSourceUtils.getSourceFromDescriptor(vp.descriptor)
|
||||
?.safeAs<KtParameter>()?.isSingleUnderscore == true
|
||||
} catch(e: NotImplementedError) {
|
||||
// Some kinds of descriptor throw in `getSourceFromDescriptor` as that method is not normally expected to
|
||||
// be applied to synthetic functions.
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) =
|
||||
try {
|
||||
DescriptorToSourceUtils.getSourceFromDescriptor(vp.descriptor)
|
||||
?.safeAs<KtParameter>()?.isSingleUnderscore == true
|
||||
} catch(e: NotImplementedError) {
|
||||
// Some kinds of descriptor throw in `getSourceFromDescriptor` as that method is not normally expected to
|
||||
// be applied to synthetic functions.
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) =
|
||||
try {
|
||||
DescriptorToSourceUtils.getSourceFromDescriptor(vp.descriptor)
|
||||
?.safeAs<KtParameter>()?.isSingleUnderscore == true
|
||||
} catch(e: NotImplementedError) {
|
||||
// Some kinds of descriptor throw in `getSourceFromDescriptor` as that method is not normally expected to
|
||||
// be applied to synthetic functions.
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) =
|
||||
try {
|
||||
DescriptorToSourceUtils.getSourceFromDescriptor(vp.descriptor)
|
||||
?.safeAs<KtParameter>()?.isSingleUnderscore == true
|
||||
} catch(e: NotImplementedError) {
|
||||
// Some kinds of descriptor throw in `getSourceFromDescriptor` as that method is not normally expected to
|
||||
// be applied to synthetic functions.
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) = vp.origin == IrDeclarationOrigin.UNDERSCORE_PARAMETER
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
|
||||
fun isUnderscoreParameter(vp: IrValueParameter) = vp.origin == IrDeclarationOrigin.UNDERSCORE_PARAMETER
|
||||
4
java/ql/lib/change-notes/2022-08-03-properties.md
Normal file
4
java/ql/lib/change-notes/2022-08-03-properties.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added a data-flow model for the `setProperty` method of `java.util.Properties`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved analysis of the Android class `AsyncTask` so that data can properly flow through its methods according to the life-cycle steps described here: https://developer.android.com/reference/android/os/AsyncTask#the-4-steps.
|
||||
@@ -244,6 +244,9 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
|
||||
"java.util;Properties;true;getProperty;(String);;Argument[-1].MapValue;ReturnValue;value;manual",
|
||||
"java.util;Properties;true;getProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual",
|
||||
"java.util;Properties;true;getProperty;(String,String);;Argument[1];ReturnValue;value;manual",
|
||||
"java.util;Properties;true;setProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual",
|
||||
"java.util;Properties;true;setProperty;(String,String);;Argument[0];Argument[-1].MapKey;value;manual",
|
||||
"java.util;Properties;true;setProperty;(String,String);;Argument[1];Argument[-1].MapValue;value;manual",
|
||||
"java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual",
|
||||
"java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual",
|
||||
"java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual",
|
||||
|
||||
@@ -4,19 +4,62 @@ import java
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.FlowSteps
|
||||
|
||||
/**
|
||||
* Models the value-preserving step from `asyncTask.execute(params)` to `AsyncTask::doInBackground(params)`.
|
||||
/*
|
||||
* The following flow steps aim to model the life-cycle of `AsyncTask`s described here:
|
||||
* https://developer.android.com/reference/android/os/AsyncTask#the-4-steps
|
||||
*/
|
||||
private class AsyncTaskAdditionalValueStep extends AdditionalValueStep {
|
||||
|
||||
/**
|
||||
* A taint step from the vararg arguments of `AsyncTask::execute` and `AsyncTask::executeOnExecutor`
|
||||
* to the parameter of `AsyncTask::doInBackground`.
|
||||
*/
|
||||
private class AsyncTaskExecuteAdditionalValueStep extends AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(ExecuteAsyncTaskMethodAccess ma, AsyncTaskRunInBackgroundMethod m |
|
||||
DataFlow::getInstanceArgument(ma).getType() = m.getDeclaringType() and
|
||||
DataFlow::getInstanceArgument(ma).getType() = m.getDeclaringType()
|
||||
|
|
||||
node1.asExpr() = ma.getParamsArgument() and
|
||||
node2.asParameter() = m.getParameter(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value-preserving step from the return value of `AsyncTask::doInBackground`
|
||||
* to the parameter of `AsyncTask::onPostExecute`.
|
||||
*/
|
||||
private class AsyncTaskOnPostExecuteAdditionalValueStep extends AdditionalValueStep {
|
||||
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(
|
||||
AsyncTaskRunInBackgroundMethod runInBackground, AsyncTaskOnPostExecuteMethod onPostExecute
|
||||
|
|
||||
onPostExecute.getDeclaringType() = runInBackground.getDeclaringType()
|
||||
|
|
||||
node1.asExpr() = any(ReturnStmt r | r.getEnclosingCallable() = runInBackground).getResult() and
|
||||
node2.asParameter() = onPostExecute.getParameter(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value-preserving step from field initializers in `AsyncTask`'s constructor or initializer method
|
||||
* to the instance parameter of `AsyncTask::runInBackground` and `AsyncTask::onPostExecute`.
|
||||
*/
|
||||
private class AsyncTaskFieldInitQualifierToInstanceParameterStep extends AdditionalValueStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(AsyncTaskInit init, Callable receiver |
|
||||
n1.(DataFlow::PostUpdateNode).getPreUpdateNode() =
|
||||
DataFlow::getFieldQualifier(any(FieldWrite f | f.getEnclosingCallable() = init)) and
|
||||
n2.(DataFlow::InstanceParameterNode).getCallable() = receiver and
|
||||
receiver.getDeclaringType() = init.getDeclaringType() and
|
||||
(
|
||||
receiver instanceof AsyncTaskRunInBackgroundMethod or
|
||||
receiver instanceof AsyncTaskOnPostExecuteMethod
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Android class `android.os.AsyncTask`.
|
||||
*/
|
||||
@@ -24,29 +67,38 @@ private class AsyncTask extends RefType {
|
||||
AsyncTask() { this.hasQualifiedName("android.os", "AsyncTask") }
|
||||
}
|
||||
|
||||
/** The constructor or initializer method of the `android.os.AsyncTask` class. */
|
||||
private class AsyncTaskInit extends Callable {
|
||||
AsyncTaskInit() {
|
||||
this.getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask and
|
||||
(this instanceof Constructor or this instanceof InitializerMethod)
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to the `execute` or `executeOnExecutor` methods of the `android.os.AsyncTask` class. */
|
||||
private class ExecuteAsyncTaskMethodAccess extends MethodAccess {
|
||||
Argument paramsArgument;
|
||||
|
||||
ExecuteAsyncTaskMethodAccess() {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask
|
||||
|
|
||||
m.getName() = "execute" and not m.isStatic() and paramsArgument = this.getArgument(0)
|
||||
or
|
||||
m.getName() = "executeOnExecutor" and paramsArgument = this.getArgument(1)
|
||||
)
|
||||
this.getMethod().hasName(["execute", "executeOnExecutor"]) and
|
||||
this.getMethod().getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof
|
||||
AsyncTask
|
||||
}
|
||||
|
||||
/** Returns the `params` argument of this call. */
|
||||
Argument getParamsArgument() { result = paramsArgument }
|
||||
Argument getParamsArgument() { result = this.getAnArgument() and result.isVararg() }
|
||||
}
|
||||
|
||||
/** The `doInBackground` method of the `android.os.AsyncTask` class. */
|
||||
private class AsyncTaskRunInBackgroundMethod extends Method {
|
||||
AsyncTaskRunInBackgroundMethod() {
|
||||
this.getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask and
|
||||
this.getName() = "doInBackground"
|
||||
this.hasName("doInBackground")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `onPostExecute` method of the `android.os.AsyncTask` class. */
|
||||
private class AsyncTaskOnPostExecuteMethod extends Method {
|
||||
AsyncTaskOnPostExecuteMethod() {
|
||||
this.getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask and
|
||||
this.hasName("onPostExecute")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ private class IntentBundleFlowSteps extends SummaryModelCsv {
|
||||
"android.os;Bundle;true;putStringArrayList;;;Argument[1];Argument[-1].MapValue;value;manual",
|
||||
"android.os;Bundle;true;readFromParcel;;;Argument[0];Argument[-1].MapKey;taint;manual",
|
||||
"android.os;Bundle;true;readFromParcel;;;Argument[0];Argument[-1].MapValue;taint;manual",
|
||||
// currently only the Extras part of the intent and the data field are fully modelled
|
||||
// currently only the Extras part of the intent and the data field are fully modeled
|
||||
"android.content;Intent;false;Intent;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual",
|
||||
"android.content;Intent;false;Intent;(Intent);;Argument[0].SyntheticField[android.content.Intent.extras].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual",
|
||||
"android.content;Intent;false;Intent;(String,Uri);;Argument[1];Argument[-1].SyntheticField[android.content.Intent.data];value;manual",
|
||||
|
||||
@@ -13,7 +13,7 @@ private class GuavaBaseCsv extends SummaryModelCsv {
|
||||
// lambda flow from Argument[1] not implemented
|
||||
"com.google.common.cache;Cache;true;get;(Object,Callable);;Argument[-1].MapValue;ReturnValue;value;manual",
|
||||
"com.google.common.cache;Cache;true;getIfPresent;(Object);;Argument[-1].MapValue;ReturnValue;value;manual",
|
||||
// the true flow to MapKey of ReturnValue for getAllPresent is the intersection of the these inputs, but intersections cannot be modelled fully accurately.
|
||||
// the true flow to MapKey of ReturnValue for getAllPresent is the intersection of the these inputs, but intersections cannot be modeled fully accurately.
|
||||
"com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual",
|
||||
"com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[0].Element;ReturnValue.MapKey;value;manual",
|
||||
"com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual",
|
||||
|
||||
@@ -13,8 +13,8 @@ private class GuavaCollectCsv extends SummaryModelCsv {
|
||||
row =
|
||||
[
|
||||
//"package;type;overrides;name;signature;ext;inputspec;outputspec;kind",
|
||||
// Methods depending on lambda flow are not currently modelled
|
||||
// Methods depending on stronger aliasing properties than we support are also not modelled.
|
||||
// Methods depending on lambda flow are not currently modeled
|
||||
// Methods depending on stronger aliasing properties than we support are also not modeled.
|
||||
"com.google.common.collect;ArrayListMultimap;true;create;(Multimap);;Argument[0].MapKey;ReturnValue.MapKey;value;manual",
|
||||
"com.google.common.collect;ArrayListMultimap;true;create;(Multimap);;Argument[0].MapValue;ReturnValue.MapValue;value;manual",
|
||||
"com.google.common.collect;ArrayTable;true;create;(Iterable,Iterable);;Argument[0].Element;ReturnValue.SyntheticField[com.google.common.collect.Table.rowKey];value;manual",
|
||||
|
||||
@@ -160,7 +160,7 @@ private class SpringXssSink extends XSS::XssSink {
|
||||
|
|
||||
// If a Spring request mapping method is either annotated with @ResponseBody (or equivalent),
|
||||
// or returns a HttpEntity or sub-type, then the return value of the method is converted into
|
||||
// a HTTP reponse using a HttpMessageConverter implementation. The implementation is chosen
|
||||
// a HTTP response using a HttpMessageConverter implementation. The implementation is chosen
|
||||
// based on the return type of the method, and the Accept header of the request.
|
||||
//
|
||||
// By default, the only message converter which produces a response which is vulnerable to
|
||||
|
||||
@@ -6,7 +6,7 @@ private import semmle.code.java.regex.regex
|
||||
/**
|
||||
* An element containing a regular expression term, that is, either
|
||||
* a string literal (parsed as a regular expression; the root of the parse tree)
|
||||
* or another regular expression term (a decendent of the root).
|
||||
* or another regular expression term (a descendant of the root).
|
||||
*
|
||||
* For sequences and alternations, we require at least two children.
|
||||
* Otherwise, we wish to represent the term differently.
|
||||
@@ -52,7 +52,7 @@ private newtype TRegExpParent =
|
||||
/**
|
||||
* An element containing a regular expression term, that is, either
|
||||
* a string literal (parsed as a regular expression; the root of the parse tree)
|
||||
* or another regular expression term (a decendent of the root).
|
||||
* or another regular expression term (a descendant of the root).
|
||||
*/
|
||||
class RegExpParent extends TRegExpParent {
|
||||
/** Gets a textual representation of this element. */
|
||||
|
||||
@@ -62,7 +62,7 @@ abstract class RegexString extends StringLiteral {
|
||||
|
||||
/**
|
||||
* Helper predicate for `quote`.
|
||||
* Holds if the char at `pos` is the one-based `index`th occurence of a quote delimiter (`\Q` or `\E`)
|
||||
* Holds if the char at `pos` is the one-based `index`th occurrence of a quote delimiter (`\Q` or `\E`)
|
||||
* Result is `true` for `\Q` and `false` for `\E`.
|
||||
*/
|
||||
private boolean quoteDelimiter(int index, int pos) {
|
||||
|
||||
@@ -28,4 +28,6 @@ class SensitiveLoggerConfiguration extends TaintTracking::Configuration {
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) {
|
||||
sanitizer.asExpr() instanceof LiveLiteral
|
||||
}
|
||||
|
||||
override predicate isSanitizerIn(Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ class ExternalApi extends Callable {
|
||||
TaintTracking::localAdditionalTaintStep(this.getAnInput(), _)
|
||||
}
|
||||
|
||||
/** Holds if this API is is a constructor without parameters. */
|
||||
/** Holds if this API is a constructor without parameters. */
|
||||
private predicate isParameterlessConstructor() {
|
||||
this instanceof Constructor and this.getNumberOfParameters() = 0
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* The query `java/sensitive-log` has been improved to no longer report results that are effectively duplicates due to one source flowing to another source.
|
||||
@@ -4,17 +4,13 @@ edges
|
||||
| FileService.java:21:28:21:64 | getStringExtra(...) : Object | FileService.java:25:42:25:50 | localPath : Object |
|
||||
| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | FileService.java:40:41:40:55 | params : Object[] |
|
||||
| FileService.java:25:13:25:51 | makeParamsToExecute(...) [[]] : Object | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] |
|
||||
| FileService.java:25:13:25:51 | makeParamsToExecute(...) [[]] : Object | FileService.java:40:41:40:55 | params [[]] : Object |
|
||||
| FileService.java:25:42:25:50 | localPath : Object | FileService.java:25:13:25:51 | makeParamsToExecute(...) [[]] : Object |
|
||||
| FileService.java:25:42:25:50 | localPath : Object | FileService.java:32:13:32:28 | sourceUri : Object |
|
||||
| FileService.java:32:13:32:28 | sourceUri : Object | FileService.java:35:17:35:25 | sourceUri : Object |
|
||||
| FileService.java:34:20:36:13 | {...} [[]] : Object | FileService.java:34:20:36:13 | new Object[] [[]] : Object |
|
||||
| FileService.java:35:17:35:25 | sourceUri : Object | FileService.java:34:20:36:13 | {...} [[]] : Object |
|
||||
| FileService.java:40:41:40:55 | params : Object[] | FileService.java:44:33:44:52 | (...)... : Object |
|
||||
| FileService.java:40:41:40:55 | params [[]] : Object | FileService.java:44:44:44:49 | params [[]] : Object |
|
||||
| FileService.java:44:33:44:52 | (...)... : Object | FileService.java:45:53:45:59 | ...[...] |
|
||||
| FileService.java:44:44:44:49 | params [[]] : Object | FileService.java:44:44:44:52 | ...[...] : Object |
|
||||
| FileService.java:44:44:44:52 | ...[...] : Object | FileService.java:44:33:44:52 | (...)... : Object |
|
||||
| LeakFileActivity2.java:15:13:15:18 | intent : Intent | LeakFileActivity2.java:16:26:16:31 | intent : Intent |
|
||||
| LeakFileActivity2.java:16:26:16:31 | intent : Intent | FileService.java:20:31:20:43 | intent : Intent |
|
||||
| LeakFileActivity.java:14:35:14:38 | data : Intent | LeakFileActivity.java:18:40:18:59 | contentIntent : Intent |
|
||||
@@ -34,10 +30,7 @@ nodes
|
||||
| FileService.java:34:20:36:13 | {...} [[]] : Object | semmle.label | {...} [[]] : Object |
|
||||
| FileService.java:35:17:35:25 | sourceUri : Object | semmle.label | sourceUri : Object |
|
||||
| FileService.java:40:41:40:55 | params : Object[] | semmle.label | params : Object[] |
|
||||
| FileService.java:40:41:40:55 | params [[]] : Object | semmle.label | params [[]] : Object |
|
||||
| FileService.java:44:33:44:52 | (...)... : Object | semmle.label | (...)... : Object |
|
||||
| FileService.java:44:44:44:49 | params [[]] : Object | semmle.label | params [[]] : Object |
|
||||
| FileService.java:44:44:44:52 | ...[...] : Object | semmle.label | ...[...] : Object |
|
||||
| FileService.java:45:53:45:59 | ...[...] | semmle.label | ...[...] |
|
||||
| LeakFileActivity2.java:15:13:15:18 | intent : Intent | semmle.label | intent : Intent |
|
||||
| LeakFileActivity2.java:16:26:16:31 | intent : Intent | semmle.label | intent : Intent |
|
||||
|
||||
@@ -3583,7 +3583,7 @@ funcExprs.kt:
|
||||
# 27| 2: [Method] invoke
|
||||
# 27| 3: [TypeAccess] int
|
||||
#-----| 4: (Parameters)
|
||||
# 27| 0: [Parameter] <anonymous parameter 0>
|
||||
# 27| 0: [Parameter] p0
|
||||
# 27| 0: [TypeAccess] int
|
||||
# 27| 5: [BlockStmt] { ... }
|
||||
# 27| 0: [ReturnStmt] return ...
|
||||
@@ -3629,9 +3629,9 @@ funcExprs.kt:
|
||||
# 30| 2: [Method] invoke
|
||||
# 30| 3: [TypeAccess] int
|
||||
#-----| 4: (Parameters)
|
||||
# 30| 0: [Parameter] <anonymous parameter 0>
|
||||
# 30| 0: [Parameter] p0
|
||||
# 30| 0: [TypeAccess] int
|
||||
# 30| 1: [Parameter] <anonymous parameter 1>
|
||||
# 30| 1: [Parameter] p1
|
||||
# 30| 0: [TypeAccess] int
|
||||
# 30| 5: [BlockStmt] { ... }
|
||||
# 30| 0: [ReturnStmt] return ...
|
||||
@@ -3652,9 +3652,9 @@ funcExprs.kt:
|
||||
# 31| 2: [Method] invoke
|
||||
# 31| 3: [TypeAccess] int
|
||||
#-----| 4: (Parameters)
|
||||
# 31| 0: [Parameter] <anonymous parameter 0>
|
||||
# 31| 0: [Parameter] p0
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 1: [Parameter] <anonymous parameter 1>
|
||||
# 31| 1: [Parameter] p1
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 5: [BlockStmt] { ... }
|
||||
# 31| 0: [ReturnStmt] return ...
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.internal.DataFlowPrivate
|
||||
|
||||
// Stop external filepaths from appearing in the results
|
||||
class ClassOrInterfaceLocation extends ClassOrInterface {
|
||||
@@ -30,9 +29,9 @@ query predicate variableInitializerType(
|
||||
decl.getInitializer().getType() = t2 and
|
||||
t2.extendsOrImplements(t3) and
|
||||
(
|
||||
compatible = true and compatibleTypes(t1, t2)
|
||||
compatible = true and haveIntersection(t1, t2)
|
||||
or
|
||||
compatible = false and not compatibleTypes(t1, t2)
|
||||
compatible = false and notHaveIntersection(t1, t2)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| test.kt:5:9:5:9 | p0 | p0 |
|
||||
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
|
||||
var x: Int
|
||||
get() = 1
|
||||
set(_) { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Parameter p
|
||||
where p.getCallable().fromSource()
|
||||
select p, p.getName()
|
||||
@@ -88,4 +88,23 @@ public class Test {
|
||||
Properties clean = new Properties();
|
||||
sink(clean.getProperty("key", tainted)); // Flow
|
||||
}
|
||||
|
||||
public void run5() {
|
||||
Properties p = new Properties();
|
||||
p.setProperty("key", tainted);
|
||||
sink(p.getProperty("key")); // Flow
|
||||
sink(p.getProperty("key", "defaultValue")); // Flow
|
||||
}
|
||||
|
||||
public void run6() {
|
||||
Properties p = new Properties();
|
||||
sink(p.put("key", tainted)); // No flow
|
||||
sink(p.put("key", "notTainted")); // Flow
|
||||
}
|
||||
|
||||
public void run7() {
|
||||
Properties p = new Properties();
|
||||
sink(p.setProperty("key", tainted)); // No flow
|
||||
sink(p.setProperty("key", "notTainted")); // Flow
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,3 +14,7 @@
|
||||
| Test.java:84:18:84:24 | tainted | Test.java:85:10:85:29 | getProperty(...) |
|
||||
| Test.java:84:18:84:24 | tainted | Test.java:86:10:86:45 | getProperty(...) |
|
||||
| Test.java:89:35:89:41 | tainted | Test.java:89:10:89:42 | getProperty(...) |
|
||||
| Test.java:94:26:94:32 | tainted | Test.java:95:10:95:29 | getProperty(...) |
|
||||
| Test.java:94:26:94:32 | tainted | Test.java:96:10:96:45 | getProperty(...) |
|
||||
| Test.java:101:23:101:29 | tainted | Test.java:102:10:102:35 | put(...) |
|
||||
| Test.java:107:31:107:37 | tainted | Test.java:108:10:108:43 | setProperty(...) |
|
||||
|
||||
@@ -3,5 +3,5 @@ import semmle.code.java.dataflow.ModulusAnalysis
|
||||
import semmle.code.java.dataflow.Bound
|
||||
|
||||
from Expr e, Bound b, int delta, int mod
|
||||
where exprModulus(e, b, delta, mod)
|
||||
where exprModulus(e, b, delta, mod) and e.getCompilationUnit().fromSource()
|
||||
select e, b.toString(), delta, mod
|
||||
|
||||
@@ -8,5 +8,5 @@ private string getDirectionString(boolean d) {
|
||||
}
|
||||
|
||||
from Expr e, Bound b, int delta, boolean upper, Reason reason
|
||||
where bounded(e, b, delta, upper, reason)
|
||||
where bounded(e, b, delta, upper, reason) and e.getCompilationUnit().fromSource()
|
||||
select e, b.toString(), delta, getDirectionString(upper), reason
|
||||
|
||||
@@ -10,16 +10,19 @@ public class Test {
|
||||
|
||||
public void test() {
|
||||
TestAsyncTask t = new TestAsyncTask();
|
||||
t.execute(source("execute"));
|
||||
t.executeOnExecutor(null, source("executeOnExecutor"));
|
||||
t.execute(source("execute"), null);
|
||||
t.executeOnExecutor(null, source("executeOnExecutor"), null);
|
||||
SafeAsyncTask t2 = new SafeAsyncTask();
|
||||
t2.execute("safe");
|
||||
TestConstructorTask t3 = new TestConstructorTask(source("constructor"), "safe");
|
||||
t3.execute(source("params"));
|
||||
}
|
||||
|
||||
private class TestAsyncTask extends AsyncTask<Object, Object, Object> {
|
||||
@Override
|
||||
protected Object doInBackground(Object... params) {
|
||||
sink(params); // $ hasValueFlow=execute hasValueFlow=executeOnExecutor
|
||||
sink(params[0]); // $ hasTaintFlow=execute hasTaintFlow=executeOnExecutor
|
||||
sink(params[1]); // $ SPURIOUS: hasTaintFlow=execute hasTaintFlow=executeOnExecutor
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -27,8 +30,40 @@ public class Test {
|
||||
private class SafeAsyncTask extends AsyncTask<Object, Object, Object> {
|
||||
@Override
|
||||
protected Object doInBackground(Object... params) {
|
||||
sink(params); // Safe
|
||||
sink(params[0]); // Safe
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class TestConstructorTask extends AsyncTask<Object, Object, Object> {
|
||||
private Object field;
|
||||
private Object safeField;
|
||||
private Object initField;
|
||||
{
|
||||
initField = Test.source("init");
|
||||
}
|
||||
|
||||
public TestConstructorTask(Object field, Object safeField) {
|
||||
this.field = field;
|
||||
this.safeField = safeField;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doInBackground(Object... params) {
|
||||
sink(params[0]); // $ hasTaintFlow=params
|
||||
sink(field); // $ hasValueFlow=constructor
|
||||
sink(safeField); // Safe
|
||||
sink(initField); // $ hasValueFlow=init
|
||||
return params[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object param) {
|
||||
sink(param); // $ hasTaintFlow=params
|
||||
sink(field); // $ hasValueFlow=constructor
|
||||
sink(safeField); // Safe
|
||||
sink(initField); // $ hasValueFlow=init
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,2 @@
|
||||
import java
|
||||
import TestUtilities.InlineFlowTest
|
||||
|
||||
class AsyncTaskTest extends InlineFlowTest {
|
||||
override TaintTracking::Configuration getTaintFlowConfig() { none() }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
| BooleanLiterals.java:5:3:5:6 | true | true | true |
|
||||
| BooleanLiterals.java:6:3:6:7 | false | false | false |
|
||||
| BooleanLiterals.java:8:8:8:26 | 4\\u0072\\u0075\\u0065 | true | true |
|
||||
| BooleanLiterals.java:8:3:8:26 | \\u0074\\u0072\\u0075\\u0065 | true | true |
|
||||
| BooleanLiterals.java:13:3:13:6 | true | true | true |
|
||||
| BooleanLiterals.java:13:11:13:14 | true | true | true |
|
||||
| BooleanLiterals.java:14:3:14:7 | false | false | false |
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
| CharLiterals.java:18:3:18:10 | '\\uDC00' | \ufffd | 56320 |
|
||||
| CharLiterals.java:20:3:20:16 | '\\u005C\\u005C' | \\ | 92 |
|
||||
| CharLiterals.java:21:3:21:16 | '\\u005C\\u0027' | ' | 39 |
|
||||
| CharLiterals.java:22:8:22:15 | 7a\\u0027 | a | 97 |
|
||||
| CharLiterals.java:22:3:22:15 | \\u0027a\\u0027 | a | 97 |
|
||||
| CharLiterals.java:27:4:27:6 | 'a' | a | 97 |
|
||||
| CharLiterals.java:28:4:28:6 | 'a' | a | 97 |
|
||||
| CharLiterals.java:33:3:33:5 | 'a' | a | 97 |
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
| DoubleLiterals.java:17:3:17:10 | 4.9e-324 | 4.9E-324 | 4.9E-324 |
|
||||
| DoubleLiterals.java:18:3:18:28 | 0x0.0_0000_0000_0001P-1022 | 4.9E-324 | 4.9E-324 |
|
||||
| DoubleLiterals.java:19:3:19:13 | 0x1.0P-1074 | 4.9E-324 | 4.9E-324 |
|
||||
| DoubleLiterals.java:21:8:21:20 | 0\\u002E\\u0030 | 0.0 | 0.0 |
|
||||
| DoubleLiterals.java:21:3:21:20 | \\u0030\\u002E\\u0030 | 0.0 | 0.0 |
|
||||
| DoubleLiterals.java:26:4:26:6 | 0.0 | 0.0 | 0.0 |
|
||||
| DoubleLiterals.java:27:4:27:6 | 0.0 | 0.0 | 0.0 |
|
||||
| DoubleLiterals.java:28:4:28:6 | 1.0 | 1.0 | 1.0 |
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
| FloatLiterals.java:16:3:16:10 | 1.4e-45f | 1.4E-45 | 1.4E-45 |
|
||||
| FloatLiterals.java:17:3:17:18 | 0x0.000002P-126f | 1.4E-45 | 1.4E-45 |
|
||||
| FloatLiterals.java:18:3:18:13 | 0x1.0P-149f | 1.4E-45 | 1.4E-45 |
|
||||
| FloatLiterals.java:20:8:20:26 | 0\\u002E\\u0030\\u0066 | 0.0 | 0.0 |
|
||||
| FloatLiterals.java:20:3:20:26 | \\u0030\\u002E\\u0030\\u0066 | 0.0 | 0.0 |
|
||||
| FloatLiterals.java:25:4:25:6 | 0.f | 0.0 | 0.0 |
|
||||
| FloatLiterals.java:26:4:26:6 | 0.f | 0.0 | 0.0 |
|
||||
| FloatLiterals.java:27:4:27:7 | 1.0f | 1.0 | 1.0 |
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import semmle.code.java.Expr
|
||||
|
||||
from FloatLiteral lit
|
||||
class SrcFloatingPointLiteral extends FloatLiteral {
|
||||
SrcFloatingPointLiteral() { this.getCompilationUnit().fromSource() }
|
||||
}
|
||||
|
||||
from SrcFloatingPointLiteral lit
|
||||
select lit, lit.getValue(), lit.getFloatValue()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
| IntegerLiterals.java:23:3:23:13 | 0xffff_ffff | -1 | -1 |
|
||||
| IntegerLiterals.java:24:3:24:16 | 0377_7777_7777 | -1 | -1 |
|
||||
| IntegerLiterals.java:25:3:25:43 | 0b1111_1111_1111_1111_1111_1111_1111_1111 | -1 | -1 |
|
||||
| IntegerLiterals.java:27:8:27:8 | 0 | 0 | 0 |
|
||||
| IntegerLiterals.java:27:3:27:8 | \\u0030 | 0 | 0 |
|
||||
| IntegerLiterals.java:32:4:32:4 | 0 | 0 | 0 |
|
||||
| IntegerLiterals.java:33:4:33:4 | 0 | 0 | 0 |
|
||||
| IntegerLiterals.java:34:4:34:4 | 1 | 1 | 1 |
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import semmle.code.java.Expr
|
||||
|
||||
from IntegerLiteral lit
|
||||
class SrcIntegerLiteral extends IntegerLiteral {
|
||||
SrcIntegerLiteral() { this.getCompilationUnit().fromSource() }
|
||||
}
|
||||
|
||||
from SrcIntegerLiteral lit
|
||||
select lit, lit.getValue(), lit.getIntValue()
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import java
|
||||
|
||||
from Literal l
|
||||
class SrcLiteral extends Literal {
|
||||
SrcLiteral() { this.getCompilationUnit().fromSource() }
|
||||
}
|
||||
|
||||
from SrcLiteral l
|
||||
where
|
||||
l instanceof IntegerLiteral or
|
||||
l instanceof LongLiteral or
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
| LongLiterals.java:23:3:23:24 | 0xffff_ffff_ffff_ffffL | -1 |
|
||||
| LongLiterals.java:24:3:24:31 | 017_7777_7777_7777_7777_7777L | -1 |
|
||||
| LongLiterals.java:25:3:25:84 | 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L | -1 |
|
||||
| LongLiterals.java:27:8:27:14 | 0\\u004C | 0 |
|
||||
| LongLiterals.java:27:3:27:14 | \\u0030\\u004C | 0 |
|
||||
| LongLiterals.java:32:4:32:5 | 0L | 0 |
|
||||
| LongLiterals.java:33:4:33:5 | 0L | 0 |
|
||||
| LongLiterals.java:34:4:34:5 | 1L | 1 |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| NullLiterals.java:5:3:5:6 | null | null |
|
||||
| NullLiterals.java:7:8:7:26 | null | null |
|
||||
| NullLiterals.java:7:3:7:26 | null | null |
|
||||
| NullLiterals.java:12:12:12:15 | null | null |
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
| StringLiterals.java:29:3:29:10 | "\\uDC00" | \ufffd | |
|
||||
| StringLiterals.java:30:3:30:31 | "hello\\uD800hello\\uDC00world" | hello\ufffdhello\ufffdworld | |
|
||||
| StringLiterals.java:32:3:32:16 | "\\u005C\\u0022" | " | |
|
||||
| StringLiterals.java:33:8:33:20 | 2\\u0061\\u0022 | a | |
|
||||
| StringLiterals.java:33:3:33:20 | \\u0022\\u0061\\u0022 | a | |
|
||||
| StringLiterals.java:38:3:40:5 | """ \t \n\t\ttest "text" and escaped \\u0022\n\t\t""" | test "text" and escaped "\n | text-block |
|
||||
| StringLiterals.java:42:3:44:5 | """\n\t\t\tindented\n\t\t""" | \tindented\n | text-block |
|
||||
| StringLiterals.java:45:3:47:5 | """\n\tno indentation last line\n\t\t""" | no indentation last line\n | text-block |
|
||||
@@ -35,7 +35,7 @@
|
||||
| StringLiterals.java:70:3:71:18 | """\n\t\t3 quotes:""\\"""" | 3 quotes:""" | text-block |
|
||||
| StringLiterals.java:72:3:75:5 | """\n\t\tline \\\n\t\tcontinuation \\\n\t\t""" | line continuation | text-block |
|
||||
| StringLiterals.java:76:3:80:5 | """\n\t\tExplicit line breaks:\\n\n\t\t\\r\\n\n\t\t\\r\n\t\t""" | Explicit line breaks:\n\n\r\n\n\r\n | text-block |
|
||||
| StringLiterals.java:83:10:85:16 | 2"\\u0022\n\t\ttest\n\t\t\\u0022\\uu0022" | test\n | |
|
||||
| StringLiterals.java:83:3:85:16 | \\uuu0022"\\u0022\n\t\ttest\n\t\t\\u0022\\uu0022" | test\n | |
|
||||
| StringLiterals.java:91:3:91:19 | "hello" + "world" | helloworld | |
|
||||
| StringLiterals.java:92:3:93:20 | """\n\t\thello""" + "world" | helloworld | text-block |
|
||||
| StringLiterals.java:94:10:94:12 | "a" | a | |
|
||||
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args --enable-preview -source 16 -target 16
|
||||
//semmle-extractor-options: --javac-args -source 17 -target 17
|
||||
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args --enable-preview -source 16 -target 16
|
||||
//semmle-extractor-options: --javac-args -source 17 -target 17
|
||||
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args --enable-preview -source 16 -target 16
|
||||
//semmle-extractor-options: --javac-args -source 17 -target 17
|
||||
|
||||
Reference in New Issue
Block a user