source: trunk/third/mozilla/caps/src/nsJSPrincipals.cpp @ 22152

Revision 22152, 7.4 KB checked in by rbasch, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22151, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Netscape Public License
6 * Version 1.1 (the "License"); you may not use this file except in
7 * compliance with the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/NPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the NPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the NPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39#include "nsString.h"
40#include "nsIObjectOutputStream.h"
41#include "nsIObjectInputStream.h"
42#include "nsJSPrincipals.h"
43#include "plstr.h"
44#include "nsXPIDLString.h"
45#include "nsCOMPtr.h"
46#include "jsapi.h"
47#include "jsxdrapi.h"
48#include "nsIJSRuntimeService.h"
49#include "nsIServiceManager.h"
50#include "nsMemory.h"
51
52JS_STATIC_DLL_CALLBACK(void *)
53nsGetPrincipalArray(JSContext *cx, JSPrincipals *prin)
54{
55    return nsnull;
56}
57
58JS_STATIC_DLL_CALLBACK(JSBool)
59nsGlobalPrivilegesEnabled(JSContext *cx, JSPrincipals *jsprin)
60{
61    return JS_TRUE;
62}
63
64JS_STATIC_DLL_CALLBACK(JSBool)
65nsJSPrincipalsSubsume(JSPrincipals *jsprin, JSPrincipals *other)
66{
67    nsJSPrincipals *nsjsprin = NS_STATIC_CAST(nsJSPrincipals *, jsprin);
68    nsJSPrincipals *nsother  = NS_STATIC_CAST(nsJSPrincipals *, other);
69
70    nsCOMPtr<nsISubsumingPrincipal> subjsprin =
71        do_QueryInterface(nsjsprin->nsIPrincipalPtr);
72    if (!subjsprin) {
73        return JS_FALSE;
74    }
75
76    JSBool result;
77    nsresult rv = subjsprin->Subsumes(nsother->nsIPrincipalPtr, &result);
78    return NS_SUCCEEDED(rv) && result;
79}
80
81JS_STATIC_DLL_CALLBACK(void)
82nsDestroyJSPrincipals(JSContext *cx, struct JSPrincipals *jsprin)
83{
84    nsJSPrincipals *nsjsprin = NS_STATIC_CAST(nsJSPrincipals *, jsprin);
85
86    // We need to destroy the nsIPrincipal. We'll do this by adding
87    // to the refcount and calling release
88
89    // Note that we don't want to use NS_IF_RELEASE because it will try
90    // to set nsjsprin->nsIPrincipalPtr to nsnull *after* nsjsprin has
91    // already been destroyed.
92#ifdef NS_BUILD_REFCNT_LOGGING
93    // The refcount logging considers AddRef-to-1 to indicate creation,
94    // so trick it into thinking it's otherwise, but balance the
95    // Release() we do below.
96    nsjsprin->refcount++;
97    nsjsprin->nsIPrincipalPtr->AddRef();
98    nsjsprin->refcount--;
99#else
100    nsjsprin->refcount++;
101#endif
102    if (nsjsprin->nsIPrincipalPtr)
103        nsjsprin->nsIPrincipalPtr->Release();
104    // The nsIPrincipal that we release owns the JSPrincipal struct,
105    // so we don't need to worry about "codebase"
106}
107
108JS_STATIC_DLL_CALLBACK(JSBool)
109nsTranscodeJSPrincipals(JSXDRState *xdr, JSPrincipals **jsprinp)
110{
111    nsresult rv;
112
113    if (xdr->mode == JSXDR_ENCODE) {
114        nsIObjectOutputStream *stream =
115            NS_REINTERPRET_CAST(nsIObjectOutputStream*, xdr->userdata);
116
117        // Flush xdr'ed data to the underlying object output stream.
118        uint32 size;
119        char *data = (char*) ::JS_XDRMemGetData(xdr, &size);
120
121        rv = stream->Write32(size);
122        if (NS_SUCCEEDED(rv)) {
123            rv = stream->WriteBytes(data, size);
124            if (NS_SUCCEEDED(rv)) {
125                ::JS_XDRMemResetData(xdr);
126
127                // Require that GetJSPrincipals has been called already by the
128                // code that compiled the script that owns the principals.
129                nsJSPrincipals *nsjsprin =
130                    NS_STATIC_CAST(nsJSPrincipals*, *jsprinp);
131
132                rv = stream->WriteObject(nsjsprin->nsIPrincipalPtr, PR_TRUE);
133            }
134        }
135    } else {
136        NS_ASSERTION(JS_XDRMemDataLeft(xdr) == 0, "XDR out of sync?!");
137        nsIObjectInputStream *stream =
138            NS_REINTERPRET_CAST(nsIObjectInputStream*, xdr->userdata);
139
140        nsCOMPtr<nsIPrincipal> prin;
141        rv = stream->ReadObject(PR_TRUE, getter_AddRefs(prin));
142        if (NS_SUCCEEDED(rv)) {
143            PRUint32 size;
144            rv = stream->Read32(&size);
145            if (NS_SUCCEEDED(rv)) {
146                char *data = nsnull;
147                if (size != 0)
148                    rv = stream->ReadBytes(size, &data);
149                if (NS_SUCCEEDED(rv)) {
150                    char *olddata;
151                    uint32 oldsize;
152
153                    // Any decode-mode JSXDRState whose userdata points to an
154                    // nsIObjectInputStream instance must use nsMemory to Alloc
155                    // and Free its data buffer.  Swap the new buffer we just
156                    // read for the old, exhausted data.
157                    olddata = (char*) ::JS_XDRMemGetData(xdr, &oldsize);
158                    nsMemory::Free(olddata);
159                    ::JS_XDRMemSetData(xdr, data, size);
160
161                    prin->GetJSPrincipals(xdr->cx, jsprinp);
162                }
163            }
164        }
165    }
166
167    if (NS_FAILED(rv)) {
168        ::JS_ReportError(xdr->cx, "can't %scode principals (failure code %x)",
169                         (xdr->mode == JSXDR_ENCODE) ? "en" : "de",
170                         (unsigned int) rv);
171        return JS_FALSE;
172    }
173    return JS_TRUE;
174}
175
176nsresult
177nsJSPrincipals::Startup()
178{
179    static const char rtsvc_id[] = "@mozilla.org/js/xpc/RuntimeService;1";
180    nsCOMPtr<nsIJSRuntimeService> rtsvc(do_GetService(rtsvc_id));
181    if (!rtsvc)
182        return NS_ERROR_FAILURE;
183
184    JSRuntime *rt;
185    rtsvc->GetRuntime(&rt);
186    NS_ASSERTION(rt != nsnull, "no JSRuntime?!");
187
188    JSPrincipalsTranscoder oldpx;
189    oldpx = ::JS_SetPrincipalsTranscoder(rt, nsTranscodeJSPrincipals);
190    NS_ASSERTION(oldpx == nsnull, "oops, JS_SetPrincipalsTranscoder wars!");
191
192    return NS_OK;
193}
194
195nsJSPrincipals::nsJSPrincipals()
196{
197    codebase = nsnull;
198    getPrincipalArray = nsGetPrincipalArray;
199    globalPrivilegesEnabled = nsGlobalPrivilegesEnabled;
200    refcount = 0;
201    destroy = nsDestroyJSPrincipals;
202    subsume = nsJSPrincipalsSubsume;
203    nsIPrincipalPtr = nsnull;
204}
205
206nsresult
207nsJSPrincipals::Init(nsIPrincipal *aPrincipal, const char *aCodebase)
208{
209    if (nsIPrincipalPtr) {
210        NS_ERROR("Init called twice!");
211        return NS_ERROR_UNEXPECTED;
212    }
213
214    nsIPrincipalPtr = aPrincipal;
215    codebase = PL_strdup(aCodebase);
216    if (!codebase)
217        return NS_ERROR_OUT_OF_MEMORY;
218
219    return NS_OK;
220}
221
222nsJSPrincipals::~nsJSPrincipals()
223{
224    if (codebase)
225        PL_strfree(codebase);
226}
Note: See TracBrowser for help on using the repository browser.