1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
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
15 * The Original Code is mozilla.org code.
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.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "xpcprivate.h"
40 #include "nsIObjectOutputStream.h"
41 #include "nsIObjectInputStream.h"
42 #include "nsJSPrincipals.h"
44 #include "nsXPIDLString.h"
48 #include "nsIJSRuntimeService.h"
49 #include "nsIServiceManager.h"
51 #include "nsStringBuffer.h"
54 nsGetPrincipalArray(JSContext
*cx
, JSPrincipals
*prin
)
60 nsGlobalPrivilegesEnabled(JSContext
*cx
, JSPrincipals
*jsprin
)
66 nsJSPrincipalsSubsume(JSPrincipals
*jsprin
, JSPrincipals
*other
)
68 nsJSPrincipals
*nsjsprin
= static_cast<nsJSPrincipals
*>(jsprin
);
69 nsJSPrincipals
*nsother
= static_cast<nsJSPrincipals
*>(other
);
72 nsresult rv
= nsjsprin
->nsIPrincipalPtr
->Subsumes(nsother
->nsIPrincipalPtr
,
74 return NS_SUCCEEDED(rv
) && result
;
78 nsDestroyJSPrincipals(JSContext
*cx
, struct JSPrincipals
*jsprin
)
80 nsJSPrincipals
*nsjsprin
= static_cast<nsJSPrincipals
*>(jsprin
);
82 // We need to destroy the nsIPrincipal. We'll do this by adding
83 // to the refcount and calling release
85 // Note that we don't want to use NS_IF_RELEASE because it will try
86 // to set nsjsprin->nsIPrincipalPtr to nsnull *after* nsjsprin has
87 // already been destroyed.
88 #ifdef NS_BUILD_REFCNT_LOGGING
89 // The refcount logging considers AddRef-to-1 to indicate creation,
90 // so trick it into thinking it's otherwise, but balance the
91 // Release() we do below.
93 nsjsprin
->nsIPrincipalPtr
->AddRef();
98 nsjsprin
->nsIPrincipalPtr
->Release();
99 // The nsIPrincipal that we release owns the JSPrincipal struct,
100 // so we don't need to worry about "codebase"
104 nsTranscodeJSPrincipals(JSXDRState
*xdr
, JSPrincipals
**jsprinp
)
108 if (xdr
->mode
== JSXDR_ENCODE
) {
109 nsIObjectOutputStream
*stream
=
110 reinterpret_cast<nsIObjectOutputStream
*>(xdr
->userdata
);
112 // Flush xdr'ed data to the underlying object output stream.
114 char *data
= (char*) ::JS_XDRMemGetData(xdr
, &size
);
116 rv
= stream
->Write32(size
);
117 if (NS_SUCCEEDED(rv
)) {
118 rv
= stream
->WriteBytes(data
, size
);
119 if (NS_SUCCEEDED(rv
)) {
120 ::JS_XDRMemResetData(xdr
);
122 // Require that GetJSPrincipals has been called already by the
123 // code that compiled the script that owns the principals.
124 nsJSPrincipals
*nsjsprin
=
125 static_cast<nsJSPrincipals
*>(*jsprinp
);
127 rv
= stream
->WriteObject(nsjsprin
->nsIPrincipalPtr
, PR_TRUE
);
131 NS_ASSERTION(JS_XDRMemDataLeft(xdr
) == 0, "XDR out of sync?!");
132 nsIObjectInputStream
*stream
=
133 reinterpret_cast<nsIObjectInputStream
*>(xdr
->userdata
);
135 nsCOMPtr
<nsIPrincipal
> prin
;
136 rv
= stream
->ReadObject(PR_TRUE
, getter_AddRefs(prin
));
137 if (NS_SUCCEEDED(rv
)) {
139 rv
= stream
->Read32(&size
);
140 if (NS_SUCCEEDED(rv
)) {
143 rv
= stream
->ReadBytes(size
, &data
);
144 if (NS_SUCCEEDED(rv
)) {
148 // Any decode-mode JSXDRState whose userdata points to an
149 // nsIObjectInputStream instance must use nsMemory to Alloc
150 // and Free its data buffer. Swap the new buffer we just
151 // read for the old, exhausted data.
152 olddata
= (char*) ::JS_XDRMemGetData(xdr
, &oldsize
);
153 nsMemory::Free(olddata
);
154 ::JS_XDRMemSetData(xdr
, data
, size
);
156 prin
->GetJSPrincipals(xdr
->cx
, jsprinp
);
163 ::JS_ReportError(xdr
->cx
, "can't %scode principals (failure code %x)",
164 (xdr
->mode
== JSXDR_ENCODE
) ? "en" : "de",
172 nsJSPrincipals::Startup()
174 nsCOMPtr
<nsIJSRuntimeService
> rtsvc
= nsXPConnect::GetXPConnect();
176 return NS_ERROR_FAILURE
;
179 rtsvc
->GetRuntime(&rt
);
180 NS_ASSERTION(rt
!= nsnull
, "no JSRuntime?!");
182 JSSecurityCallbacks
*callbacks
= JS_GetRuntimeSecurityCallbacks(rt
);
183 NS_ASSERTION(callbacks
, "Need a callbacks struct by now!");
185 NS_ASSERTION(!callbacks
->principalsTranscoder
,
186 "oops, JS_SetPrincipalsTranscoder wars!");
188 callbacks
->principalsTranscoder
= nsTranscodeJSPrincipals
;
192 nsJSPrincipals::nsJSPrincipals()
195 getPrincipalArray
= nsGetPrincipalArray
;
196 globalPrivilegesEnabled
= nsGlobalPrivilegesEnabled
;
198 destroy
= nsDestroyJSPrincipals
;
199 subsume
= nsJSPrincipalsSubsume
;
200 nsIPrincipalPtr
= nsnull
;
204 nsJSPrincipals::Init(nsIPrincipal
*aPrincipal
, const nsCString
& aCodebase
)
206 if (nsIPrincipalPtr
) {
207 NS_ERROR("Init called twice!");
208 return NS_ERROR_UNEXPECTED
;
211 nsIPrincipalPtr
= aPrincipal
;
212 nsStringBuffer
* buf
= nsStringBuffer::FromString(aCodebase
);
216 data
= static_cast<char*>(buf
->Data());
218 PRUint32 len
= aCodebase
.Length();
219 buf
= nsStringBuffer::Alloc(len
+ 1); // addrefs
221 return NS_ERROR_OUT_OF_MEMORY
;
223 data
= static_cast<char*>(buf
->Data());
224 memcpy(data
, aCodebase
.get(), len
);
233 nsJSPrincipals::~nsJSPrincipals()
236 nsStringBuffer::FromData(codebase
)->Release();