IG: report invalid argument to $#s in malformed format string (IDEA-157921)

This commit is contained in:
Bas Leijdekkers
2017-06-04 12:32:12 +02:00
parent 2c244ef193
commit 72749bfab4
3 changed files with 46 additions and 1 deletions
@@ -188,7 +188,7 @@ class FormatDecode {
case 's': // formatted string (general)
case 'S':
checkFlags(flagBits, LEFT_JUSTIFY | ALTERNATE | PREVIOUS, specifier);
allowed = ALL_VALIDATOR;
allowed = (flagBits & ALTERNATE) != 0 ? new FormattableValidator(specifier) : ALL_VALIDATOR;
break;
case 'c': // unicode character
case 'C':
@@ -390,6 +390,18 @@ class FormatDecode {
}
}
private static class FormattableValidator extends Validator {
public FormattableValidator(String specifier) {
super(specifier);
}
@Override
public boolean valid(PsiType type) {
return InheritanceUtil.isInheritor(type, "java.util.Formattable");
}
}
private static class MultiValidator extends Validator {
private final Set<Validator> validators = new HashSet<>(3);
@@ -3,6 +3,7 @@ package com.siyeh.igtest.bugs.malformed_format_string;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Locale;
import java.util.Formattable;
public class MalformedFormatString {
@@ -117,3 +118,15 @@ public class MalformedFormatString {
System.out.printf("%o %<o", 15);
}
}
class A {
void m(Formattable f) {
// each one fails, but inspection doesn't find the problems
String.format("%#s", <warning descr="Argument type 'int' does not match the type of the format specifier '%#s'">0</warning>);
String.format("%#s", <warning descr="Argument type 'float' does not match the type of the format specifier '%#s'">0.5f</warning>);
String.format("%#S", <warning descr="Argument type 'String' does not match the type of the format specifier '%#S'">"hello"</warning>);
String.format("%#S", <warning descr="Argument type 'int' does not match the type of the format specifier '%#S'">new Object().hashCode()</warning>);
// should be OK
String.format("%#s", f);
}
}
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.bugs;
import com.intellij.codeInspection.InspectionProfileEntry;
@@ -22,6 +37,11 @@ public class MalformedFormatStringInspectionTest extends LightInspectionTestCase
@Override
protected String[] getEnvironmentClasses() {
return new String[] {
"package java.util;" +
"public interface Formattable {" +
" void formatTo(Formatter formatter, int flags, int width, int precision);" +
"}",
"package java.time.temporal;\n" +
"public interface TemporalAccessor {\n" +
" boolean isSupported(TemporalField field);\n" +