Closed Bug 169321 Opened 22 years ago Closed 22 years ago

Passing strings generated by .match or .substr into Components.lookupMethod() will throw an exception.

Categories

(Core :: XPConnect, defect)

x86
Linux
defect
Not set
normal

Tracking

()

VERIFIED FIXED

People

(Reporter: caillon, Assigned: dbradley)

References

Details

Attachments

(2 files, 2 obsolete files)

Using linux 2002091704:

Components.lookupMethod(window, 'alert'); // works fine
Components.lookupMethod(window, 'alert'.substr(0)); // doesn't work

in nsXPCComponents::LookupMethod() we are failing somewhere around here:

    // this will do verification and the method lookup for us
    XPCCallContext inner_cc(JS_CALLER, cx, obj, nsnull, argv[1]);

    // was our jsobject really a wrapped native at all?
    XPCWrappedNative* wrapper = inner_cc.GetWrapper();
    if(!wrapper || !wrapper->IsValid())
        return NS_ERROR_XPC_BAD_CONVERT_JS;


I have a testcase which needs to be loaded as chrome to work properly.
Attached file Testcase
This needs chrome priveleges to run properly.  Click on each of the three
buttons.  You should get no exceptions thrown.
After talking this over with Brendan I think we know what the deail is. I
realized that XPConnect does jsval compares when looking for names in the
wrappers n' what not and that means that the strings that are passed to the code
that does that lookup must be atomized strings, the results from .match() et al
are not atomized. Should be trivial to fix in XPConnect.
Heh, I just came to the same conclusion after wading through exotic JS and
xpconnect code.
I'd say don't intern the name parameter to Components.lookupMethod, rather just
do string compares if the jsvals don't match.

/be
Is there a cleaner way to do this in XPConnect? I don't know...
Attachment #99613 - Attachment description: This should fix the problem by atimizing the name. → This should fix the problem by atomizing the name.
I'm not happy with this one, though -- and not just cuz it doesn't compile! (I
didn't bother to get the #includes right).  Because other callers funnel down
to XPCNativeInterface::FindMember, I'm concerned that a patch of this sort will
hurt all callers who *do* ensure uniquely associated string jsvals, and will
even ding app performance.

Can't we make nsXPCComponents::LookupMethod pay the price, and only that method
pay the price, of having to do strcmp if the jsval match fails?

/be
Of course, the lots of garbage atoms case arises only if the name parameter
doesn't match an existing interface's method.  Right?  Or do we lazily load
interface methods and intern their name strings only on demand, or some such?  I
could see jst's patch making things no worse in the good case, where the name
does match.  But in the mismatch case, it would seem to pin garbage atoms.

/be
BTW, there's a workaround for this bug.  Try using the computed string (the
substr() return value, e.g.) as an index into a dummy object.  Then you should
be able to use that same string value (you'll have to save the r.v. or whatever
the result of the computation is in a variable) as the name parameter to
Components.lookupMethod.

/be
Comment on attachment 99614 [details] [diff] [review]
alterna-patch that avoids creating lots of garbage atoms that are pinned forever

I don't think this is acceptable for performance reasons (as brendan already
mentioned), and I don't know the XPConnect code well enough if we can easily
make Components.lookupMethod() pay the price here w/o atimizing the strings
that come through it.

Brendan, does the JS_ValueToId() call always intern the string? What I really
want is something like JS_StringToAtimzedValue(), can't that be done w/o
pinning the strings for the life of the runtime?
Damn, my finger's don't work today, s/atimize/atomize/g, in all 3 places (at
least), geez!
Argh, I am losing it.  JS_ValueToId does not pin the atom for the life of the
runtime, as JS_InternString does.  I should have read jst's patch.  It's good to
go.  I'll invalidate mine.

/be
Comment on attachment 99613 [details] [diff] [review]
This should fix the problem by atomizing the name.

The only issue is that if the GC could nest somewhere after the JS_ValueToId
and JS_IdToValue, it might collect the atom out from under this code (mismatch
case, obviously).  You want to set argv[1] = name; after the JS_IdToValue call
succeeds.

Also, you are not respecting prevailing style: don't brace those single-line
return statement then clauses at all (but if you had to brace, put the opening
brace on its own line).

Fix the bug and nit, and sr=brendan@mozilla.org.

/be
Attachment #99614 - Attachment is obsolete: true
Attachment #99613 - Attachment is obsolete: true
Comment on attachment 99619 [details] [diff] [review]
Fix the issues brought up by brendan.

sr=brendan@mozilla.org

/be
Attachment #99619 - Flags: superreview+
Comment on attachment 99619 [details] [diff] [review]
Fix the issues brought up by brendan.

r=dbradley

Good catch. The only thing that concerns me is that if another such function is
added it may end up with the same problem. Insuring the name is atomized at
XPCCallContext::SetName or within the FindMember functions is probably ideal,
but more risky. In the wrapped JS case, XPConnect asserts that the jsval's
coming in are atomized. It would be nice if we could ensure this within the
FindMember functions. Moving this assert to XPCCallContext might be beneficial.
At least it would have caught this instance.
Attachment #99619 - Flags: review+
Comment on attachment 99619 [details] [diff] [review]
Fix the issues brought up by brendan.

r=jag
Last night on IRC, Johnny gave me permission to check this in for him if
dbradley was one of the r=s.  He is, so I just landed this.

Thanks all, for getting this bug fixed so quickly!
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Verified FIXED by comparing these Mozilla trunk binaries on WinNT:

                         2002-09-11-xx
                         2002-09-24-xx 

STEPS TO REPRODUCE
un-jar comm.jar, replace pageInfo.xul with the testcase, and re-jar:

1. cd bin/chrome
2. jar xf comm.jar
3. cd content
4. cd navigator
5. replace pageInfo.xul with the testcase above
6. cd ../..
7. jar cf comm.jar content
8. Launch the browser
9. Do View > Page Info to bring up the testcase
10. Click on the three buttons 


binary 2002-09-11-xx: the try...catch code in the testcase caught
and alerted exceptions generated by clicking on the 2nd and 3rd buttons:

  Exception.. "Component returned failure code: NS_ERROR_XPC_BAD_CONVERT_JS
  in nsIXPCComponents.lookupMethod ..."


binary 2002-09-24-xx:  I got no exceptions by clicking any of the buttons.
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: