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 ***** */
39 #include "nsIObjectOutputStream.h"
40 #include "nsIObjectInputStream.h"
41 #include "nsJSPrincipals.h"
43 #include "nsXPIDLString.h"
47 #include "nsIJSRuntimeService.h"
48 #include "nsIServiceManager.h"
50 #include "nsStringBuffer.h"
53 nsGetPrincipalArray(JSContext
*cx
, JSPrincipals
*prin
)
59 nsGlobalPrivilegesEnabled(JSContext
*cx
, JSPrincipals
*jsprin
)
65 nsJSPrincipalsSubsume(JSPrincipals
*jsprin
, JSPrincipals
*other
)
67 nsJSPrincipals
*nsjsprin
= static_cast<nsJSPrincipals
*>(jsprin
);
68 nsJSPrincipals
*nsother
= static_cast<nsJSPrincipals
*>(other
);
71 nsresult rv
= nsjsprin
->nsIPrincipalPtr
->Subsumes(nsother
->nsIPrincipalPtr
,
73 return NS_SUCCEEDED(rv
) && result
;
77 nsDestroyJSPrincipals(JSContext
*cx
, struct JSPrincipals
*jsprin
)
79 nsJSPrincipals
*nsjsprin
= static_cast<nsJSPrincipals
*>(jsprin
);
81 // We need to destroy the nsIPrincipal. We'll do this by adding
82 // to the refcount and calling release
84 // Note that we don't want to use NS_IF_RELEASE because it will try
85 // to set nsjsprin->nsIPrincipalPtr to nsnull *after* nsjsprin has
86 // already been destroyed.
87 #ifdef NS_BUILD_REFCNT_LOGGING
88 // The refcount logging considers AddRef-to-1 to indicate creation,
89 // so trick it into thinking it's otherwise, but balance the
90 // Release() we do below.
92 nsjsprin
->nsIPrincipalPtr
->AddRef();
97 nsjsprin
->nsIPrincipalPtr
->Release();
98 // The nsIPrincipal that we release owns the JSPrincipal struct,
99 // so we don't need to worry about "codebase"
103 nsTranscodeJSPrincipals(JSXDRState
*xdr
, JSPrincipals
**jsprinp
)
107 if (xdr
->mode
== JSXDR_ENCODE
) {
108 nsIObjectOutputStream
*stream
=
109 reinterpret_cast<nsIObjectOutputStream
*>(xdr
->userdata
);
111 // Flush xdr'ed data to the underlying object output stream.
113 char *data
= (char*) ::JS_XDRMemGetData(xdr
, &size
);
115 rv
= stream
->Write32(size
);
116 if (NS_SUCCEEDED(rv
)) {
117 rv
= stream
->WriteBytes(data
, size
);
118 if (NS_SUCCEEDED(rv
)) {
119 ::JS_XDRMemResetData(xdr
);
121 // Require that GetJSPrincipals has been called already by the
122 // code that compiled the script that owns the principals.
123 nsJSPrincipals
*nsjsprin
=
124 static_cast<nsJSPrincipals
*>(*jsprinp
);
126 rv
= stream
->WriteObject(nsjsprin
->nsIPrincipalPtr
, PR_TRUE
);
130 NS_ASSERTION(JS_XDRMemDataLeft(xdr
) == 0, "XDR out of sync?!");
131 nsIObjectInputStream
*stream
=
132 reinterpret_cast<nsIObjectInputStream
*>(xdr
->userdata
);
134 nsCOMPtr
<nsIPrincipal
> prin
;
135 rv
= stream
->ReadObject(PR_TRUE
, getter_AddRefs(prin
));
136 if (NS_SUCCEEDED(rv
)) {
138 rv
= stream
->Read32(&size
);
139 if (NS_SUCCEEDED(rv
)) {
142 rv
= stream
->ReadBytes(size
, &data
);
143 if (NS_SUCCEEDED(rv
)) {
147 // Any decode-mode JSXDRState whose userdata points to an
148 // nsIObjectInputStream instance must use nsMemory to Alloc
149 // and Free its data buffer. Swap the new buffer we just
150 // read for the old, exhausted data.
151 olddata
= (char*) ::JS_XDRMemGetData(xdr
, &oldsize
);
152 nsMemory::Free(olddata
);
153 ::JS_XDRMemSetData(xdr
, data
, size
);
155 prin
->GetJSPrincipals(xdr
->cx
, jsprinp
);
162 ::JS_ReportError(xdr
->cx
, "can't %scode principals (failure code %x)",
163 (xdr
->mode
== JSXDR_ENCODE
) ? "en" : "de",
171 nsJSPrincipals::Startup()
173 static const char rtsvc_id
[] = "@mozilla.org/js/xpc/RuntimeService;1";
174 nsCOMPtr
<nsIJSRuntimeService
> rtsvc(do_GetService(rtsvc_id
));
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();