Xiaoven / codegex

A light-weight tools like spotbugs
GNU Lesser General Public License v2.1
1 stars 0 forks source link

有趣的 Bug Instances #133

Open Xiaoven opened 3 years ago

Xiaoven commented 3 years ago
  1. 我们特有的 False Positive (如 regex的不准确而造成的、无法获取上下文信息造成的等等)
  2. spotbugs 和我们都有的 False Positive
  3. spotbugs 特有的 False Negative (我们没有)
  4. 我们特有的 False Negative (spotbugs 没有)
  5. spotbugs 特有的 FPs (如由于 representation 造成的)
Xiaoven commented 3 years ago

类型 1

因为没有看import,所以造成这个错误

// https://github.com/magento/magento2-phpstorm-plugin/pull/466/files#diff-028a687773810be34d4f962c42ff2634925954908884573d0f2bfacf44a6e2aaR118
import com.magento.idea.magento2plugin.magento.packages.File;
...
final String[] handlerDirectories = messageQueueClassDataName.getPath().split(
                File.separator
        );
// https://github.com/magento/magento2-phpstorm-plugin/blob/2f786d1b203c81138df234d668f48e1fbb90798f/src/com/magento/idea/magento2plugin/magento/packages/File.java
package com.magento.idea.magento2plugin.magento.packages;

public class File {
    public static String separator = "/";
}
Xiaoven commented 3 years ago

类型 3

Spotbugs 使用的是 bytecode representation,无法检测 method call 类型的 self computation

实际跑的时候发现的

// https://github.com/qiniu/android-sdk/pull/453/files/7356a6c3eccb942fa90edc9e537b36b349ebc89a#diff-7f67181eef83b3f2ab332944daecf2a476d7f0f78028876136b5dd05641b0755

// https://github.com/qiniu/android-sdk/blob/7356a6c3eccb942fa90edc9e537b36b349ebc89a/library/src/main/java/com/qiniu/android/http/request/HttpSingleRequest.java#L177
double second = requestMetrics.endDate.getTime() - requestMetrics.endDate.getTime();    // duration 太短了,结果等于0

endDatejava.util.Date 类的,用 spotbugs 试验了以下代码,没有发现 warning

double main(java.util.Date endDate){
        double second = endDate.getTime() - endDate.getTime();
        return second;
    }
Xiaoven commented 3 years ago

还没有找到例子来确定,先划掉

类型 5

Spotbugs 使用 bytecode representation,根据它的 description 所言,Arrays.asArray(new String[] { "a" }).toArray() will return a String []. SpotBugs attempts to detect and suppress such cases, but may miss some.

而我们直接匹配形如 (String[]) c.toArray() 的代码,如果开发者使用了 Arrays.asArray(new String[] { "a" }) 的,就不会用 (String[]) 的强制转换,也就不会被我们的工具匹配到。

pattern 描述如下:

According to the Correctness, BC: Impossible downcast of toArray() result (BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY).

This code is casting the result of calling toArray() on a collection to a type more specific than Object[], as in:

String[] getAsArray(Collection<String> c) {
    return (String[]) c.toArray();
}

This will usually fail by throwing a ClassCastException. The toArray() of almost all collections return an Object[]. They can't really do anything else, since the Collection object has no reference to the declared generic type of the collection.

The correct way to do get an array of a specific type from a collection is to use c.toArray(new String[]); or c.toArray(new String[c.size()]); (the latter is slightly more efficient).

There is one common/known exception to this. The toArray() method of lists returned by Arrays.asList(...) will return a covariantly typed array. For example, Arrays.asArray(new String[] { "a" }).toArray() will return a String [].

Xiaoven commented 3 years ago

类型 3

RV: Random value from 0 to 1 is coerced to the integer 0 (RV_01_TO_INT)

int main(int size, Random r){
        return (int) r.nextFloat() * size;
    }

spotbugs 检查 Math.random()randomObject.nextDouble() 方法,但似乎忘了检查 randomObject.nextFloat() 方法

Xiaoven commented 3 years ago

类型 1

DLS_DEAD_LOCAL_INCREMENT_IN_RETURN

无法区分 field 和 local var

// https://github.com/MaximSinyak/Java/pull/6/files/3ef2bc97335cb0a460f77ff812a42223b055b539#diff-91797b67aa94c9428c50548a3fdb1dd145643d7dbe93fe4296019f7c70435e0a
@@ -0,0 +1,31 @@
 package ru.geekbrains.lesson_6;

 public class Main {
     private static int countCat = 0;
     private static int countDog = 0;

      public static void main(String[] args){
          makeCat("Barsik", 30, 40);
          makeCat("Murzik", 250, 4);
          makeDog("Tuzik", 400, 4);
          makeDog("Sharik", 600, 9);
          makeDog("Barbos", 300, 20);
 System.out.println("Создано: кошек - " + countCat +  "; собак - " + countDog);

      }

      public static int makeCat(String name, int run, int swim){
          Cat cat = new Cat(name, run, swim);
          cat.run();
          cat.swim();
          return countCat++;
Xiaoven commented 3 years ago

类型 3

DLS_OVERWRITTEN_INCREMENT

设计阶段发现的 FP

i = 2 + (i++);

spotbugs 只能检查 i = i++;i = i--; 这种简单的 expression

Xiaoven commented 3 years ago

类型 3 spotbugs 特有的 False Negative (我们没有)

SA_SELF_COMPUTATION

// https://github.com/wensiqun/asmsupport/blob/master/asmsupport-sample/src/main/java/cn/wensiqun/asmsupport/sample/core/operators/LogicalOperatorGenerate.java#L37
            System.out.printf("%s\n%s: %b\n%s: %b\n%s: %b\n%s: %b\n\n",
                "Boolean logical AND (&)", "false & false", (false & false),
                "false & true", (false & true), "true & false", (true & false),
                "true & true", (true & true));
stan6 commented 3 years ago

类型 3

DLS_OVERWRITTEN_INCREMENT

设计阶段发现的 FP

i = 2 + (i--);

spotbugs 只能检查 i = i++;

Need to file a new bug report. In the bug description of DLS_DEAD_LOCAL_INCREMENT_IN_RETURN, http://findbugs.sourceforge.net/bugDescriptions.html, they mentioned increment/decrement but they didn't actually support any decrement based on their code at https://github.com/spotbugs/spotbugs/blob/a6f9acb2932b54f5b70ea8bc206afb552321a222/spotbugs/src/main/java/edu/umd/cs/findbugs/detect/FindDeadLocalStores.java. We can file one GItHub issue complaining about these two patterns DLS_OVERWRITTEN_INCREMENT and DLS_DEAD_LOCAL_INCREMENT_IN_RETURN because it o

stan6 commented 3 years ago

To check: Inconsistent documentation 类型 3

DLS_DEAD_LOCAL_INCREMENT_IN_RETURN DLS_OVERWRITTEN_INCREMENT Both patterns do not check for decrement in their code (they used IINC to check for the increment instruction) but DLS_DEAD_LOCAL_INCREMENT_IN_RETURN mentioned "decrement" in their description and DLS_OVERWRITTEN_INCREMENT didn't mention. Need to check if both patterns support decrement.

zhouyinn commented 3 years ago

increment / decrement 相关的 bug patterns

DLS_DEAD_LOCAL_INCREMENT_IN_RETURN DLS_OVERWRITTEN_INCREMENT VO_VOLATILE_INCREMENT QF_QUESTIONABLE_FOR_LOOP

all of them support ++ and -- detection


//DLS_DEAD_LOCAL_INCREMENT_IN_RETURN for ++
    int testDLS_DEAD_LOCAL_INCREMENT_IN_RETURN(){
        int i = 0;
        return i++;
    }

    //DLS_DEAD_LOCAL_INCREMENT_IN_RETURN for --
    int testDLS_DEAD_LOCAL_INCREMENT_IN_RETURN1(){
        int i = 0;
        return i--;
    }

    //DLS_OVERWRITTEN_INCREMENT for ++
    void testDLS_OVERWRITTEN_INCREMENT(){
        int i = 0;
        i = i++;
    }

    //DLS_OVERWRITTEN_INCREMENT for --
    void testDLS_OVERWRITTEN_INCREMENT1(){
        int i = 0;
        i = i--;
    }

    //VO_VOLATILE_INCREMENT for ++
    private volatile int x = 0;
    void testVO_VOLATILE_INCREMENT() {
        try {
            x++; // Warning -- False Positive!
        } finally {
        }
    }

    //VO_VOLATILE_INCREMENT for --
    void testVO_VOLATILE_INCREMENT1() {
        try {
            x--; // Warning -- False Positive!
        } finally {
        }
    }

    //QF_QUESTIONABLE_FOR_LOOP for ++
    void testQF_QUESTIONABLE_FOR_LOOP(){
        int i = 0;
        for(int j = 0; j < 10; i++){
            System.out.println("Hi");
            j++;
        }
    }

    //QF_QUESTIONABLE_FOR_LOOP for --
    void testQF_QUESTIONABLE_FOR_LOOP1(){
        int i = 0;
        for(int j = 0; j < 10; i--){
            System.out.println("Hi");
            j--;
        }
    }

only the description of DLS_DEAD_LOCAL_INCREMENT_IN_RETURN mentioned **increment|decrement**
zhouyinn commented 3 years ago

复现 SA_LOCAL_SELF_COMPUTATION @stan6


int testSA_FIELD_SELF_COMPUTATION(){
      int flags = 1;
      return flags ^ flags; // warning SA_LOCAL_SELF_COMPUTATION
  }

  int testSA_FIELD_SELF_COMPUTATION1(){
      int flags = 1;
      return flags & flags; // no warning (False negative)
  }

  int testSA_FIELD_SELF_COMPUTATION2(){
      int flags = 1;
      return flags - flags; // no warning (False negative)
  }

  int testSA_FIELD_SELF_COMPUTATION3(){
      int flags = 1;
      return flags + flags; // no warning (False negative)
  }

  double testSA_FIELD_SELF_COMPUTATION4(java.util.Date endDate){
      // Should report nonsensical self computation
      double temp = endDate.getTime();
      double second = temp - temp; // no warning (False negative)
      return second;
  }
zhouyinn commented 3 years ago

image In https://github.com/oracle/graal/pull/3288, the author complains that the warning that rbugs reported is a false positive.

image As can be seen from the figure, SpotBugs also reports the same bug.