use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class ReadParcelableDetector method visitMethod.
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression node, @NonNull UMethod method) {
PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
return;
}
if (!(CLASS_PARCEL.equals(containingClass.getQualifiedName()))) {
return;
}
List<UExpression> expressions = node.getValueArguments();
int argumentCount = expressions.size();
if (argumentCount == 0) {
String message = String.format("Using the default class loader " + "will not work if you are restoring your own classes. Consider " + "using for example `%1$s(getClass().getClassLoader())` instead.", node.getMethodName());
Location location = context.getUastLocation(node);
context.report(ISSUE, node, location, message);
} else if (argumentCount == 1) {
UExpression parameter = expressions.get(0);
if (UastLiteralUtils.isNullLiteral(parameter)) {
String message = "Passing null here (to use the default class loader) " + "will not work if you are restoring your own classes. Consider " + "using for example `getClass().getClassLoader()` instead.";
Location location = context.getUastLocation(node);
context.report(ISSUE, node, location, message);
}
}
}
use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class RegistrationDetector method reportMissing.
private static void reportMissing(@NonNull JavaContext context, @NonNull PsiClass node, @NonNull String className, @NonNull String tag) {
if (tag.equals(TAG_RECEIVER)) {
// Receivers can be registered in code; don't flag these.
return;
}
// Don't flag activities registered in test source sets
if (context.getProject().isGradleProject()) {
AndroidProject model = context.getProject().getGradleProjectModel();
if (model != null) {
String javaSource = context.file.getPath();
for (SourceProviderContainer extra : model.getDefaultConfig().getExtraSourceProviders()) {
String artifactName = extra.getArtifactName();
if (AndroidProject.ARTIFACT_ANDROID_TEST.equals(artifactName)) {
for (File file : extra.getSourceProvider().getJavaDirectories()) {
if (SdkUtils.startsWithIgnoreCase(javaSource, file.getPath())) {
return;
}
}
}
}
for (ProductFlavorContainer container : model.getProductFlavors()) {
for (SourceProviderContainer extra : container.getExtraSourceProviders()) {
String artifactName = extra.getArtifactName();
if (AndroidProject.ARTIFACT_ANDROID_TEST.equals(artifactName)) {
for (File file : extra.getSourceProvider().getJavaDirectories()) {
if (SdkUtils.startsWithIgnoreCase(javaSource, file.getPath())) {
return;
}
}
}
}
}
}
}
Location location = context.getNameLocation(node);
String message = String.format("The `<%1$s> %2$s` is not registered in the manifest", tag, className);
context.report(ISSUE, node, location, message);
}
use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class TrustAllX509TrustManagerDetector method checkClass.
// ---- Implements ClassScanner ----
// Only used for libraries where we have to analyze bytecode
@Override
@SuppressWarnings("rawtypes")
public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) {
if (!context.isFromClassLibrary()) {
// Non-library code checked at the AST level
return;
}
if (!classNode.interfaces.contains("javax/net/ssl/X509TrustManager")) {
return;
}
List methodList = classNode.methods;
for (Object m : methodList) {
MethodNode method = (MethodNode) m;
if ("checkServerTrusted".equals(method.name) || "checkClientTrusted".equals(method.name)) {
InsnList nodes = method.instructions;
// Stays true if method doesn't perform any "real"
boolean emptyMethod = true;
// operations
for (int i = 0, n = nodes.size(); i < n; i++) {
// Future work: Improve this check to be less sensitive to irrelevant
// instructions/statements/invocations (e.g. System.out.println) by
// looking for calls that could lead to a CertificateException being
// thrown, e.g. throw statement within the method itself or invocation
// of another method that may throw a CertificateException, and only
// reporting an issue if none of these calls are found. ControlFlowGraph
// may be useful here.
AbstractInsnNode instruction = nodes.get(i);
int type = instruction.getType();
if (type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE && !(type == AbstractInsnNode.INSN && instruction.getOpcode() == Opcodes.RETURN)) {
emptyMethod = false;
break;
}
}
if (emptyMethod) {
Location location = context.getLocation(method, classNode);
context.report(ISSUE, location, getErrorMessage(method.name));
}
}
}
}
use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class UnsafeBroadcastReceiverDetector method checkOnReceive.
private static void checkOnReceive(@NonNull JavaContext context, @NonNull PsiMethod method) {
// Search for call to getAction but also search for references to aload_2,
// which indicates that the method is making use of the received intent in
// some way.
//
// If the onReceive method doesn't call getAction but does make use of
// the received intent, it is possible that it is passing it to another
// method that might be performing the getAction check, so we warn that the
// finding may be a false positive. (An alternative option would be to not
// report a finding at all in this case.)
PsiParameter parameter = method.getParameterList().getParameters()[1];
OnReceiveVisitor visitor = new OnReceiveVisitor(context.getEvaluator(), parameter);
context.getUastContext().getMethodBody(method).accept(visitor);
if (!visitor.getCallsGetAction()) {
String report;
if (!visitor.getUsesIntent()) {
report = "This broadcast receiver declares an intent-filter for a protected " + "broadcast action string, which can only be sent by the system, " + "not third-party applications. However, the receiver's onReceive " + "method does not appear to call getAction to ensure that the " + "received Intent's action string matches the expected value, " + "potentially making it possible for another actor to send a " + "spoofed intent with no action string or a different action " + "string and cause undesired behavior.";
} else {
// An alternative implementation option is to not report a finding at all in
// this case, if we are worried about false positives causing confusion or
// resulting in developers ignoring other lint warnings.
report = "This broadcast receiver declares an intent-filter for a protected " + "broadcast action string, which can only be sent by the system, " + "not third-party applications. However, the receiver's onReceive " + "method does not appear to call getAction to ensure that the " + "received Intent's action string matches the expected value, " + "potentially making it possible for another actor to send a " + "spoofed intent with no action string or a different action " + "string and cause undesired behavior. In this case, it is " + "possible that the onReceive method passed the received Intent " + "to another method that checked the action string. If so, this " + "finding can safely be ignored.";
}
Location location = context.getNameLocation(method);
context.report(ACTION_STRING, method, location, report);
}
}
use of com.android.tools.klint.detector.api.Location in project kotlin by JetBrains.
the class StringFormatDetector method checkArity.
/**
* Check that the number of arguments in the format string is consistent
* across translations, and that all arguments are used
*/
private static void checkArity(Context context, String name, List<Pair<Handle, String>> list) {
// Check to make sure that the argument counts and types are consistent
int prevCount = -1;
for (Pair<Handle, String> pair : list) {
Set<Integer> indices = new HashSet<Integer>();
int count = getFormatArgumentCount(pair.getSecond(), indices);
Handle handle = pair.getFirst();
if (prevCount != -1 && prevCount != count) {
Object clientData = handle.getClientData();
if (clientData instanceof Node) {
if (context.getDriver().isSuppressed(null, ARG_COUNT, (Node) clientData)) {
return;
}
}
Location location = handle.resolve();
Location secondary = list.get(0).getFirst().resolve();
secondary.setMessage("Conflicting number of arguments here");
location.setSecondary(secondary);
String message = String.format("Inconsistent number of arguments in formatting string `%1$s`; " + "found both %2$d and %3$d", name, prevCount, count);
context.report(ARG_COUNT, location, message);
break;
}
for (int i = 1; i <= count; i++) {
if (!indices.contains(i)) {
Object clientData = handle.getClientData();
if (clientData instanceof Node) {
if (context.getDriver().isSuppressed(null, ARG_COUNT, (Node) clientData)) {
return;
}
}
Set<Integer> all = new HashSet<Integer>();
for (int j = 1; j < count; j++) {
all.add(j);
}
all.removeAll(indices);
List<Integer> sorted = new ArrayList<Integer>(all);
Collections.sort(sorted);
Location location = handle.resolve();
String message = String.format("Formatting string '`%1$s`' is not referencing numbered arguments %2$s", name, sorted);
context.report(ARG_COUNT, location, message);
break;
}
}
prevCount = count;
}
}
Aggregations