Closed Bug 271821 Opened 21 years ago Closed 20 years ago

exception when I try to pass object inherited from nsIWebProgressListener to registerListener of nsIMsgProgress interface

Categories

(Core :: XPConnect, defect)

defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: surkov, Assigned: dbradley)

Details

Attachments

(1 file)

1.29 KB, application/vnd.mozilla.xul+xml
Details
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8a5) Gecko/20041122 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8a5) Gecko/20041122 Components.interfaces.nsIWebProgressListener is javascript object witch defines constants of the form STATE_xxx as properties. I create javascript object to pass it to registerListener method of nsIMsgProgress interface. This object realizes methods of nsIWebProgressListener interface and is inherited from Components.interfaces.nsIWebProgressListener in order to include these constants. When I try to pass it to registerListener() then I get exception Error: uncaught exception: ["Could not convert JavaScript argument arg 0 [nsIMsgProgress.registerListener]" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" ]. I don't know exactly this problem relates to xpconnect or realization of '@mozilla.org/messenger/progress;1' object. I seem the problem lies in wrong Components.interfaces.nsIWebProgressListener javascript object. Reproducible: Always Steps to Reproduce: function msgprogresslistener() { this.__proto__=Components.interfaces.nsIWebProgressListener; this.nsiprogress = Components.classes["@mozilla.org/messenger/progress;1"]. createInstance(Components.interfaces.nsIMsgProgress); this.onLocationChange=function(webProgress, request, location){} this.onProgressChange=function( webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress){} this.onSecurityChange=function( webProgress, request, state){} this.onStateChange=function(webProgress, request, stateFlags, status){} this.onStatusChange=function(webProgress, request, status, message){} this.nsiprogress.registerListener(this); } var listener=new msgprogresslistener();
1. You didn't define QueryInterface. 2. Declaring the proto as components.interfaces.nsIWhatever is unecessary. You'll want to check out http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsSample.js for an example of implementing an XPCOM interface in JS.
Status: UNCONFIRMED → RESOLVED
Closed: 21 years ago
Resolution: --- → INVALID
1. I'll define QueryInterface() the next way: this.QueryInterface=function(iid){ if(iid.equals(Components.interfaces.nsIWebProgressListener)|| iid.equals(Components.interfaces.nsISupports)) return this; Components.returnCode=Components.results.NS_ERROR_NO_INTERFACE; return null; } } 2. Declaring the proto as components.interfaces.nsIWhatever is unecessary. But it is comfortably to use defined there constants. If I'll add QueryInterface() then problem will be actual as before.
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---
I'll define QueryInterface() as this.QueryInterface=function(iid){ if(iid.equals(Components.interfaces.nsIWebProgressListener)|| iid.equals(Components.interfaces.nsISupports)) return this; } Components.returnCode=Components.results.NS_ERROR_NO_INTERFACE; return null; }
Attached file testcase
Comment on attachment 167168 [details] testcase copy to local disc and run it
So.. the problem is in fact that the proto is set to Components.interfaces.nsIWebProgressListener.... if I remove that line, everything works.
Putting Components.interfaces.nsIWebProgressListener on an objects prototype means that a QueryInterface() method is inherited (since interfaces have a QI method), so that function needs to be overridden in order for things to work right. If this is still a problem with a QueryInterface() method on the instance object that shadows the one on the proto, then there's more to this...
Johnny, see the testcase. It does have a this.QueryInterface method...
This is an automated message, with ID "auto-resolve01". This bug has had no comments for a long time. Statistically, we have found that bug reports that have not been confirmed by a second user after three months are highly unlikely to be the source of a fix to the code. While your input is very important to us, our resources are limited and so we are asking for your help in focussing our efforts. If you can still reproduce this problem in the latest version of the product (see below for how to obtain a copy) or, for feature requests, if it's not present in the latest version and you still believe we should implement it, please visit the URL of this bug (given at the top of this mail) and add a comment to that effect, giving more reproduction information if you have it. If it is not a problem any longer, you need take no action. If this bug is not changed in any way in the next two weeks, it will be automatically resolved. Thank you for your help in this matter. The latest beta releases can be obtained from: Firefox: http://www.mozilla.org/projects/firefox/ Thunderbird: http://www.mozilla.org/products/thunderbird/releases/1.5beta1.html Seamonkey: http://www.mozilla.org/projects/seamonkey/
confirm Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9a1) Gecko/20050909 SeaMonkey/1.1a
Confirming, but this may be invalid. We end up calling XPCConvert::JSObject2NativeInterface, which calls XPCWrappedNative::GetWrappedNativeOfJSObject on the JSObject passed in. This method walks the prototype chain and returns the first XPCWrappedNative that it finds in this chain. In this case, that would be the XPCWrappedNative for the nsJSIID (since we have an IID object as a prototype). So we try to QI the nsJSIID object to nsIWebProgressListener and that throws, of course... So we return false from JSObject2NativeInterface, and that makes XPConnect to throw an exception. So my only question in all this is why GetWrappedNativeOfJSObject() walks the prototype chain. I really don't understand why it's doing that. jst, you have blame for this code, but that's the XPCDOM branch landing, so maybe jband knows something about this?
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Windows 2000 → All
Hardware: PC → All
If it were up to me I'd resolve this as WONTFIX. I wouldn't say that XPCWrappedNative::GetWrappedNativeOfJSObject "returns the first XPCWrappedNative that it finds in this chain". There are a bunch of cases and various posibilities for continue'ing the proto chain walk. Also note that in the non-funobj case it starts with 'self' before walking any prototypes. Nevertheless, it is the normal case for tearoffs or 'normal' user inheritence to be implemented via the prototype chain. Arguably, we could check for an explicit QI method on the JSObject. But, I think that would add significant overhead for the *much* more common cases. And, I'm afraid to think about the security implications or what might break from that change. I think the answer for the original reporter remains "don't do that".
Yeah. That's basically what jst and I decided earlier today on irc...
Status: NEW → RESOLVED
Closed: 21 years ago20 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: