Checker CallsOnArray

belongs to group Basic
Identify suspicious calls over arrays

Frameworks supported by this checker

  • java up to 11
  • android up to API level 28
  • dotnet

Warnings generated by this checker

  • CallToToStringOnArrayWarning: toString() is called over an array [ CWE440 ]

Options accepted by this checker

  • none

Annotations understood by this checker

  • @com.juliasoft.julia.checkers.callsOnArray.ReceivesACallToToString


Description

Arrays are instances of java.lang.Object in Java. As a consequence, all methods of java.lang.Object can be invoked on arrays, However, this is not always sensible. In particular, calls to toString() yield a string derived from the unique identifier of the object, which is likely to be useless for the programmer and not her intent when she called toString().

It is possible that this warning is the consequence of refactoring, that replaced a collection class with an array but left the method calls unchanged.

Action: Replace the call with a call to java.util.Arrays.toString(array) or with an explicit iteration over the elements of the array.

Arrays are instances of System.Object in .Net. As a consequence, all methods of System.Object can be invoked on arrays, However, this is not always sensible. In particular, calls to ToString() yield a string derived from the unique identifier of the object, which is likely to be useless for the programmer and not her intent when she called ToString().

It is possible that this warning is the consequence of refactoring, that replaced a collection class with an array but left the method calls unchanged.

Action: Replace the call with a call to that return a string with the elements of array or with an explicit iteration over the elements of the array.

Examples

Consider the following program:

public class CallsOnArray {
  private static A[] array;

  public static void main(String[] args) {
    array = new A[args.length];
    for (int pos = 0; pos < args.length; pos++)
      array[pos] = new A(args[pos]);

    foo(array);

    System.out.println(array);
  }

  private static void foo(Object o) {
    String s = o.toString();
    System.out.println(s);
  }

  private static class A {
    private int f;

    private A(String s) {
      this.f = s.length();
    }

    @Override
    public String toString() {
      return String.valueOf(f);
    }
  }
}

This checker issues the following warnings:

CallsOnArray.java:11: [CallsOnArray: CallToToStringOnArrayWarning] Call to toString() on array
CallsOnArray.java:15: [CallsOnArray: CallToToStringOnArrayWarning] Call to toString() on array

At line 11, the array is passed to the println() method, that will invoke onString() on it. At line 15, the call to println() is direct and Julia recognizes that an array is passed for o, although its static type is java.lang.Object.

In this example, the programmer should probably replace line 11 with the loop:

for (int pos = 0; pos < array.length; pos++)
  System.out.println(array[pos]);

or similar.

Consider the following program:

using System;

namespace DocumentationExamples
{

    public class CallsOnArray
    {
        private static CallsOnArrayA[] array;
        public static void Main(string[] args)
        {
            array = new CallsOnArrayA[args.Length];
            for (int pos = 0; pos < args.Length; pos++)
                array[pos] = new CallsOnArrayA(args[pos]);
            Foo(array);
            Console.WriteLine(array);
        }
        private static void Foo(object o)
        {
            string s = o.ToString();
            Console.WriteLine(s);
        }
    }
  
    public class CallsOnArrayA
    {
        private int f;
        public CallsOnArrayA(string s)
        {
            f = s.Length;
        }
        public override string ToString()
        {
            return f.ToString();
        }
    }
}

This checker issues the following warnings:

DocumentationExamples.cs:15: [CallsOnArray: CallToToStringOnArrayWarning] Call to method "ToString" on array
DocumentationExamples.cs:19: [CallsOnArray: CallToToStringOnArrayWarning] Call to method "WriteLine" on array

At line 15, the array is passed to the Console.WriteLine method, that will invoke ToString() on it. At line 20, the call to Console.WriteLine is direct and Julia recognizes that an array is passed for o, although its static type is System.Object.

In this example, the programmer should probably replace the issue with a loop:

for (int pos = 0; pos < array.Length; pos++)
	Console.WriteLine(array[pos]);

or similar.