Yes, I agree with Ondrej. Take a look at the example I have
attached to this message. There are four classes A,B,C and Test as
in your example,
I wrote a little Java program, compiled
it to class files, then produced Jimple using Soot, edited the Jimple to put
the private in class B and changed the signature of the virtualinvoke in
class Test (see below) and then used Soot to produce class files from
the Jimple.
I also decompiled the new class files (files in dava/src). This gives
you a source code look at what I have. Note that
the decompiled source will not recompile because of the private f in
class B.
However, you can run the class file Test.
Try, java -verify Test
and it will say that it is running the method in class A.
Here is the jimple for Test.java,
/*****************************************
public class Test extends java.lang.Object
{
public void <init>()
{
Test r0;
r0 := @this: Test;
specialinvoke r0.<java.lang.Object: void <init>()>();
return;
}
public static void main(java.lang.String[] )
{
java.lang.String[] r0;
C $r1, r2;
r0 := @parameter0: java.lang.String[];
$r1 = new C;
specialinvoke $r1.<C: void <init>()>();
r2 = $r1;
virtualinvoke r2.<A: void f()>(); <---------------
return;
}
}
*******************************************
Look at the statement marked by the arrow. This must use the
signature A in the call to f. If either B or C is used, then
the bytecode fails when run with the verifier (and it writes out
that it is running f in B if you turn the verifier off).
Cheers, Laurie
+-------------------------------------------------------------+
| Laurie Hendren, Professor, School of Computer Science |
| McGill University |
| 318 McConnell Engineering Building tel: (514) 398-7391 |
| 3480 University Street fax: (514) 398-3883 |
| Montreal, Quebec H3A 2A7 hendren@cs.mcgill.ca |
| CANADA http://www.sable.mcgill.ca/~hendren |
+-------------------------------------------------------------+
On Thu, 6 Mar 2003, Ondrej LHOTAK wrote:
> The lookup code implemented in Soot follows the description given in the
> Java Virtual Machine Specification, under invokevirtual:
> http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokevirtual
>
> According to this description, for the example you gave, the A.f() that
> Soot returns would indeed be the correct method to invoke. Contrary to
> your claim, it is *not* true that C cannot access any f(), neither from
> A nor B.
>
> If you still think I have misunderstood the specification, please let me
> know.
>
> Ondrej
>
> On Thu, Mar 06, 2003 at 11:17:21AM -0500, Weilei Zhang wrote:
> > The following is from the method resolveConcreteDispatch in Hierarchy.java.
> > public SootMethod resolveConcreteDispatch(SootClass concreteType, SootMethod m)
> > {
> > ..........
> > while (it.hasNext())
> > {
> > SootClass c = (SootClass)it.next();
> > if (c.declaresMethod(methodSig)
> > && isVisible( c, m )
> > ) {
> > return c.getMethod(methodSig);
> > }
> > }
> > ......
> > }
> > I think the loop should be terminated once we find a SootClass c s.t. (c.declaresMethod(methodSig)&& ! isVisible( c, m )).
> > The reason is as follows: think of a Class A ,which has public method f(), Class B which extends A and has a redefined private method f(), Class C extends B and doesn't redefine method f(). Then the instance of C can't access any f(), either in A() or in B(). But in your code, A.f() will be returned.
> > However, the case I mentioned can't appear in normally compiled java code because B can't override f() in A with weaker access privileges. But maybe it will appear in maliciously/purposefully made bytecode.
> > As a conclusion, there is no problem in general cases, but there is a mistake semantically, IMHO.
> > Regards
> > -Weilei
> >
> >
> >
> >
>
Attachment:
Test.tar.gz
Description: Binary data