ArrayIndexOutOfBoundsException when using @Tested (was: "Method parameter names counting counts double for reference types") #243

Closed
alienisty opened this Issue Dec 4, 2015 · 6 comments

Projects

None yet

2 participants

@alienisty

The new ParameterNames.getSumOfArgumentSizes method counts double when a parameter is a non array reference type, because, when the code finds the ';' character, it does not increase 'i' again after the loop, causing the main loop to read it again and treat it as another parameter.

The following call, will reproduce the bug:
ParameterNames.registerName("A", PUBLIC, "m1", "(Ljava/lang/String;)", "J", "local", 2);

I also believe that the case for the array would not properly handle arrays of reference types.

I suggest using the following implementation:

private static int getSumOfArgumentSizes(@Nonnull String memberDesc)
   {
      int sum = 0;
      int i = 1;

      while (true) {
         char c = memberDesc.charAt(i);

         if (c == ')') {
            return sum;
         }

         if (c == 'L') {
            while (memberDesc.charAt(i) != ';') i++;
            sum++;
         }
         else if (c == '[') {
            while ((c = memberDesc.charAt(i)) == '[') i++;
            continue;
         }
         else if (isDoubleSizeType(c)) {
            sum += 2;
         }
         else {
            sum++;
         }
         i++;
      }
}
@rliesenfeld
Member

Without a description of the problem (from the user's perspective), a failing example test, or sufficient information for me to write a failing test, there isn't much else to go on.

@rliesenfeld rliesenfeld closed this Dec 4, 2015
@alienisty

In the description I state:

The following call, will reproduce the bug:
ParameterNames.registerName("A", PUBLIC, "m1", "(Ljava/lang/String;)", "J", "local", 2);

If that is not enough I can craft a class and a unit test using jmockit that will break, but is easy enough to inspect the implementation of ParameterNames.getSumOfArgumentSizes() and realize that it doesn't properly parse a method descriptor, as I explained as well in the description.

@alienisty

Here it is a test that causes an ArrayIndexOutOfBoundException:

public class MethodParametersMiscountingTest {

    @Tested
    private CharSequence mock;


    @Test
    public void testIssue243(@Mocked File file) {
        long variableMistakenForParameter=32L;
    }
}

And the following is a class that test for the expected parameter slots count for reference types:

public class ParameterNamesArgumentParsingTest {
    @Test
    public void testParseRefernceParameter() {
        assertEquals(1, getSumOfArgumentSizes("(Ljava/lang/String;)"));
    }

    @Test
    public void testParseArraysOfRefernceParameter() {
        assertEquals(1, getSumOfArgumentSizes("([Ljava/lang/String;)"));
    }

    private int getSumOfArgumentSizes(String memberDesc) {
        return Deencapsulation.invoke(ParameterNames.class, "getSumOfArgumentSizes", memberDesc);
    }
}
@alienisty

Hello Rogerio,
I've added comments and test cases to issue #243, which I noticed you've
already closed, so I'm not sure you would receive notifications about it.
Maybe next time give a chance to people that is trying to contribute and
help, to add more information, or have discussion, before closing issues so
swiftly.

Regards,
Alex Nistico

On Sat, 5 Dec 2015 at 02:21 Rogério Liesenfeld notifications@github.com
wrote:

Without a description of the problem (from the user's perspective), a
failing example test, or sufficient information for me to write a failing
test, there isn't much else to go on.


Reply to this email directly or view it on GitHub
#243 (comment).

Alessandro (Alex) Nistico
alienisty@gmail.com

"Any system like Eternity, which allows men to choose their own future,
will end
by choosing safety and mediocrity, and in such a Reality the stars are out
of reach."

The End of Eternity - Isaac Asimov

@rliesenfeld rliesenfeld reopened this Dec 7, 2015
@rliesenfeld rliesenfeld added bug and removed could not reproduce labels Dec 7, 2015
@rliesenfeld
Member

Thanks.

@rliesenfeld rliesenfeld self-assigned this Dec 7, 2015
@rliesenfeld
Member

The failure occurs whenever the parameter names of a method or constructor are extracted, provided there's at least one parameter of a reference type and the first local variable is of type long or double.

For example, if the test class has a @Tested class like the following, any test will fail with an ArrayIndexOutOfBoundsException:

static class ClassWithConstructorHavingReferenceTypeParameterAndDoubleSizedLocalVar
{
    ClassWithConstructorHavingReferenceTypeParameterAndDoubleSizedLocalVar(String s)
    {
        long var = 1;
    }
}

@Tested ClassWithConstructorHavingReferenceTypeParameterAndDoubleSizedLocalVar sut;
@rliesenfeld rliesenfeld changed the title from Method parameter names counting counts double for reference types to ArrayIndexOutOfBoundsException when using @Tested (was: "Method parameter names counting counts double for reference types") Dec 7, 2015
@rliesenfeld rliesenfeld added a commit that closed this issue Dec 12, 2015
@rliesenfeld rliesenfeld Fixed bug in the extraction of parameter names when using @Tested on …
…a class having a parameter of reference type and a first local variable of type long or double; closes #243.
3ebe7da
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment