1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/modules/libjar/nsJARURI.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,880 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "base/basictypes.h" 1.11 + 1.12 +#include "nsJARURI.h" 1.13 +#include "nsNetUtil.h" 1.14 +#include "nsIIOService.h" 1.15 +#include "nsIStandardURL.h" 1.16 +#include "nsCRT.h" 1.17 +#include "nsIComponentManager.h" 1.18 +#include "nsIServiceManager.h" 1.19 +#include "nsIZipReader.h" 1.20 +#include "nsReadableUtils.h" 1.21 +#include "nsAutoPtr.h" 1.22 +#include "nsNetCID.h" 1.23 +#include "nsIObjectInputStream.h" 1.24 +#include "nsIObjectOutputStream.h" 1.25 +#include "nsIProgrammingLanguage.h" 1.26 +#include "mozilla/ipc/URIUtils.h" 1.27 + 1.28 +using namespace mozilla::ipc; 1.29 + 1.30 +static NS_DEFINE_CID(kJARURICID, NS_JARURI_CID); 1.31 + 1.32 +//////////////////////////////////////////////////////////////////////////////// 1.33 + 1.34 +nsJARURI::nsJARURI() 1.35 +{ 1.36 +} 1.37 + 1.38 +nsJARURI::~nsJARURI() 1.39 +{ 1.40 +} 1.41 + 1.42 +// XXX Why is this threadsafe? 1.43 +NS_IMPL_ADDREF(nsJARURI) 1.44 +NS_IMPL_RELEASE(nsJARURI) 1.45 +NS_INTERFACE_MAP_BEGIN(nsJARURI) 1.46 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJARURI) 1.47 + NS_INTERFACE_MAP_ENTRY(nsIURI) 1.48 + NS_INTERFACE_MAP_ENTRY(nsIURL) 1.49 + NS_INTERFACE_MAP_ENTRY(nsIJARURI) 1.50 + NS_INTERFACE_MAP_ENTRY(nsISerializable) 1.51 + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) 1.52 + NS_INTERFACE_MAP_ENTRY(nsINestedURI) 1.53 + NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableURI) 1.54 + // see nsJARURI::Equals 1.55 + if (aIID.Equals(NS_GET_IID(nsJARURI))) 1.56 + foundInterface = reinterpret_cast<nsISupports*>(this); 1.57 + else 1.58 +NS_INTERFACE_MAP_END 1.59 + 1.60 +nsresult 1.61 +nsJARURI::Init(const char *charsetHint) 1.62 +{ 1.63 + mCharsetHint = charsetHint; 1.64 + return NS_OK; 1.65 +} 1.66 + 1.67 +#define NS_JAR_SCHEME NS_LITERAL_CSTRING("jar:") 1.68 +#define NS_JAR_DELIMITER NS_LITERAL_CSTRING("!/") 1.69 +#define NS_BOGUS_ENTRY_SCHEME NS_LITERAL_CSTRING("x:///") 1.70 + 1.71 +// FormatSpec takes the entry spec (including the "x:///" at the 1.72 +// beginning) and gives us a full JAR spec. 1.73 +nsresult 1.74 +nsJARURI::FormatSpec(const nsACString &entrySpec, nsACString &result, 1.75 + bool aIncludeScheme) 1.76 +{ 1.77 + // The entrySpec MUST start with "x:///" 1.78 + NS_ASSERTION(StringBeginsWith(entrySpec, NS_BOGUS_ENTRY_SCHEME), 1.79 + "bogus entry spec"); 1.80 + 1.81 + nsAutoCString fileSpec; 1.82 + nsresult rv = mJARFile->GetSpec(fileSpec); 1.83 + if (NS_FAILED(rv)) return rv; 1.84 + 1.85 + if (aIncludeScheme) 1.86 + result = NS_JAR_SCHEME; 1.87 + else 1.88 + result.Truncate(); 1.89 + 1.90 + result.Append(fileSpec + NS_JAR_DELIMITER + 1.91 + Substring(entrySpec, 5, entrySpec.Length() - 5)); 1.92 + return NS_OK; 1.93 +} 1.94 + 1.95 +nsresult 1.96 +nsJARURI::CreateEntryURL(const nsACString& entryFilename, 1.97 + const char* charset, 1.98 + nsIURL** url) 1.99 +{ 1.100 + *url = nullptr; 1.101 + 1.102 + nsCOMPtr<nsIStandardURL> stdURL(do_CreateInstance(NS_STANDARDURL_CONTRACTID)); 1.103 + if (!stdURL) { 1.104 + return NS_ERROR_OUT_OF_MEMORY; 1.105 + } 1.106 + 1.107 + // Flatten the concatenation, just in case. See bug 128288 1.108 + nsAutoCString spec(NS_BOGUS_ENTRY_SCHEME + entryFilename); 1.109 + nsresult rv = stdURL->Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, 1.110 + spec, charset, nullptr); 1.111 + if (NS_FAILED(rv)) { 1.112 + return rv; 1.113 + } 1.114 + 1.115 + return CallQueryInterface(stdURL, url); 1.116 +} 1.117 + 1.118 +//////////////////////////////////////////////////////////////////////////////// 1.119 +// nsISerializable methods: 1.120 + 1.121 +NS_IMETHODIMP 1.122 +nsJARURI::Read(nsIObjectInputStream* aInputStream) 1.123 +{ 1.124 + nsresult rv; 1.125 + 1.126 + nsCOMPtr<nsISupports> supports; 1.127 + rv = aInputStream->ReadObject(true, getter_AddRefs(supports)); 1.128 + NS_ENSURE_SUCCESS(rv, rv); 1.129 + 1.130 + mJARFile = do_QueryInterface(supports, &rv); 1.131 + NS_ENSURE_SUCCESS(rv, rv); 1.132 + 1.133 + rv = aInputStream->ReadObject(true, getter_AddRefs(supports)); 1.134 + NS_ENSURE_SUCCESS(rv, rv); 1.135 + 1.136 + mJAREntry = do_QueryInterface(supports); 1.137 + NS_ENSURE_SUCCESS(rv, rv); 1.138 + 1.139 + rv = aInputStream->ReadCString(mCharsetHint); 1.140 + return rv; 1.141 +} 1.142 + 1.143 +NS_IMETHODIMP 1.144 +nsJARURI::Write(nsIObjectOutputStream* aOutputStream) 1.145 +{ 1.146 + nsresult rv; 1.147 + 1.148 + rv = aOutputStream->WriteCompoundObject(mJARFile, NS_GET_IID(nsIURI), 1.149 + true); 1.150 + NS_ENSURE_SUCCESS(rv, rv); 1.151 + 1.152 + rv = aOutputStream->WriteCompoundObject(mJAREntry, NS_GET_IID(nsIURL), 1.153 + true); 1.154 + NS_ENSURE_SUCCESS(rv, rv); 1.155 + 1.156 + rv = aOutputStream->WriteStringZ(mCharsetHint.get()); 1.157 + return rv; 1.158 +} 1.159 + 1.160 +//////////////////////////////////////////////////////////////////////////////// 1.161 +// nsIClassInfo methods: 1.162 + 1.163 +NS_IMETHODIMP 1.164 +nsJARURI::GetInterfaces(uint32_t *count, nsIID * **array) 1.165 +{ 1.166 + *count = 0; 1.167 + *array = nullptr; 1.168 + return NS_OK; 1.169 +} 1.170 + 1.171 +NS_IMETHODIMP 1.172 +nsJARURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval) 1.173 +{ 1.174 + *_retval = nullptr; 1.175 + return NS_OK; 1.176 +} 1.177 + 1.178 +NS_IMETHODIMP 1.179 +nsJARURI::GetContractID(char * *aContractID) 1.180 +{ 1.181 + *aContractID = nullptr; 1.182 + return NS_OK; 1.183 +} 1.184 + 1.185 +NS_IMETHODIMP 1.186 +nsJARURI::GetClassDescription(char * *aClassDescription) 1.187 +{ 1.188 + *aClassDescription = nullptr; 1.189 + return NS_OK; 1.190 +} 1.191 + 1.192 +NS_IMETHODIMP 1.193 +nsJARURI::GetClassID(nsCID * *aClassID) 1.194 +{ 1.195 + *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID)); 1.196 + if (!*aClassID) 1.197 + return NS_ERROR_OUT_OF_MEMORY; 1.198 + return GetClassIDNoAlloc(*aClassID); 1.199 +} 1.200 + 1.201 +NS_IMETHODIMP 1.202 +nsJARURI::GetImplementationLanguage(uint32_t *aImplementationLanguage) 1.203 +{ 1.204 + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; 1.205 + return NS_OK; 1.206 +} 1.207 + 1.208 +NS_IMETHODIMP 1.209 +nsJARURI::GetFlags(uint32_t *aFlags) 1.210 +{ 1.211 + // XXX We implement THREADSAFE addref/release, but probably shouldn't. 1.212 + *aFlags = nsIClassInfo::MAIN_THREAD_ONLY; 1.213 + return NS_OK; 1.214 +} 1.215 + 1.216 +NS_IMETHODIMP 1.217 +nsJARURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) 1.218 +{ 1.219 + *aClassIDNoAlloc = kJARURICID; 1.220 + return NS_OK; 1.221 +} 1.222 + 1.223 +//////////////////////////////////////////////////////////////////////////////// 1.224 +// nsIURI methods: 1.225 + 1.226 +NS_IMETHODIMP 1.227 +nsJARURI::GetSpec(nsACString &aSpec) 1.228 +{ 1.229 + nsAutoCString entrySpec; 1.230 + mJAREntry->GetSpec(entrySpec); 1.231 + return FormatSpec(entrySpec, aSpec); 1.232 +} 1.233 + 1.234 +NS_IMETHODIMP 1.235 +nsJARURI::GetSpecIgnoringRef(nsACString &aSpec) 1.236 +{ 1.237 + nsAutoCString entrySpec; 1.238 + mJAREntry->GetSpecIgnoringRef(entrySpec); 1.239 + return FormatSpec(entrySpec, aSpec); 1.240 +} 1.241 + 1.242 +NS_IMETHODIMP 1.243 +nsJARURI::GetHasRef(bool *result) 1.244 +{ 1.245 + return mJAREntry->GetHasRef(result); 1.246 +} 1.247 + 1.248 +NS_IMETHODIMP 1.249 +nsJARURI::SetSpec(const nsACString& aSpec) 1.250 +{ 1.251 + return SetSpecWithBase(aSpec, nullptr); 1.252 +} 1.253 + 1.254 +nsresult 1.255 +nsJARURI::SetSpecWithBase(const nsACString &aSpec, nsIURI* aBaseURL) 1.256 +{ 1.257 + nsresult rv; 1.258 + 1.259 + nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); 1.260 + NS_ENSURE_SUCCESS(rv, rv); 1.261 + 1.262 + nsAutoCString scheme; 1.263 + rv = ioServ->ExtractScheme(aSpec, scheme); 1.264 + if (NS_FAILED(rv)) { 1.265 + // not an absolute URI 1.266 + if (!aBaseURL) 1.267 + return NS_ERROR_MALFORMED_URI; 1.268 + 1.269 + nsRefPtr<nsJARURI> otherJAR; 1.270 + aBaseURL->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR)); 1.271 + NS_ENSURE_TRUE(otherJAR, NS_NOINTERFACE); 1.272 + 1.273 + mJARFile = otherJAR->mJARFile; 1.274 + 1.275 + nsCOMPtr<nsIStandardURL> entry(do_CreateInstance(NS_STANDARDURL_CONTRACTID)); 1.276 + if (!entry) 1.277 + return NS_ERROR_OUT_OF_MEMORY; 1.278 + 1.279 + rv = entry->Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, 1.280 + aSpec, mCharsetHint.get(), otherJAR->mJAREntry); 1.281 + if (NS_FAILED(rv)) 1.282 + return rv; 1.283 + 1.284 + mJAREntry = do_QueryInterface(entry); 1.285 + if (!mJAREntry) 1.286 + return NS_NOINTERFACE; 1.287 + 1.288 + return NS_OK; 1.289 + } 1.290 + 1.291 + NS_ENSURE_TRUE(scheme.EqualsLiteral("jar"), NS_ERROR_MALFORMED_URI); 1.292 + 1.293 + nsACString::const_iterator begin, end; 1.294 + aSpec.BeginReading(begin); 1.295 + aSpec.EndReading(end); 1.296 + 1.297 + while (begin != end && *begin != ':') 1.298 + ++begin; 1.299 + 1.300 + ++begin; // now we're past the "jar:" 1.301 + 1.302 + // Search backward from the end for the "!/" delimiter. Remember, jar URLs 1.303 + // can nest, e.g.: 1.304 + // jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html 1.305 + // This gets the b.html document from out of the a.jar file, that's 1.306 + // contained within the bar.jar file. 1.307 + // Also, the outermost "inner" URI may be a relative URI: 1.308 + // jar:../relative.jar!/a.html 1.309 + 1.310 + nsACString::const_iterator delim_begin (begin), 1.311 + delim_end (end); 1.312 + 1.313 + if (!RFindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end)) 1.314 + return NS_ERROR_MALFORMED_URI; 1.315 + 1.316 + rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(), 1.317 + aBaseURL, getter_AddRefs(mJARFile)); 1.318 + if (NS_FAILED(rv)) return rv; 1.319 + 1.320 + NS_TryToSetImmutable(mJARFile); 1.321 + 1.322 + // skip over any extra '/' chars 1.323 + while (*delim_end == '/') 1.324 + ++delim_end; 1.325 + 1.326 + return SetJAREntry(Substring(delim_end, end)); 1.327 +} 1.328 + 1.329 +NS_IMETHODIMP 1.330 +nsJARURI::GetPrePath(nsACString &prePath) 1.331 +{ 1.332 + prePath = NS_JAR_SCHEME; 1.333 + return NS_OK; 1.334 +} 1.335 + 1.336 +NS_IMETHODIMP 1.337 +nsJARURI::GetScheme(nsACString &aScheme) 1.338 +{ 1.339 + aScheme = "jar"; 1.340 + return NS_OK; 1.341 +} 1.342 + 1.343 +NS_IMETHODIMP 1.344 +nsJARURI::SetScheme(const nsACString &aScheme) 1.345 +{ 1.346 + // doesn't make sense to set the scheme of a jar: URL 1.347 + return NS_ERROR_FAILURE; 1.348 +} 1.349 + 1.350 +NS_IMETHODIMP 1.351 +nsJARURI::GetUserPass(nsACString &aUserPass) 1.352 +{ 1.353 + return NS_ERROR_FAILURE; 1.354 +} 1.355 + 1.356 +NS_IMETHODIMP 1.357 +nsJARURI::SetUserPass(const nsACString &aUserPass) 1.358 +{ 1.359 + return NS_ERROR_FAILURE; 1.360 +} 1.361 + 1.362 +NS_IMETHODIMP 1.363 +nsJARURI::GetUsername(nsACString &aUsername) 1.364 +{ 1.365 + return NS_ERROR_FAILURE; 1.366 +} 1.367 + 1.368 +NS_IMETHODIMP 1.369 +nsJARURI::SetUsername(const nsACString &aUsername) 1.370 +{ 1.371 + return NS_ERROR_FAILURE; 1.372 +} 1.373 + 1.374 +NS_IMETHODIMP 1.375 +nsJARURI::GetPassword(nsACString &aPassword) 1.376 +{ 1.377 + return NS_ERROR_FAILURE; 1.378 +} 1.379 + 1.380 +NS_IMETHODIMP 1.381 +nsJARURI::SetPassword(const nsACString &aPassword) 1.382 +{ 1.383 + return NS_ERROR_FAILURE; 1.384 +} 1.385 + 1.386 +NS_IMETHODIMP 1.387 +nsJARURI::GetHostPort(nsACString &aHostPort) 1.388 +{ 1.389 + return NS_ERROR_FAILURE; 1.390 +} 1.391 + 1.392 +NS_IMETHODIMP 1.393 +nsJARURI::SetHostPort(const nsACString &aHostPort) 1.394 +{ 1.395 + return NS_ERROR_FAILURE; 1.396 +} 1.397 + 1.398 +NS_IMETHODIMP 1.399 +nsJARURI::GetHost(nsACString &aHost) 1.400 +{ 1.401 + return NS_ERROR_FAILURE; 1.402 +} 1.403 + 1.404 +NS_IMETHODIMP 1.405 +nsJARURI::SetHost(const nsACString &aHost) 1.406 +{ 1.407 + return NS_ERROR_FAILURE; 1.408 +} 1.409 + 1.410 +NS_IMETHODIMP 1.411 +nsJARURI::GetPort(int32_t *aPort) 1.412 +{ 1.413 + return NS_ERROR_FAILURE; 1.414 +} 1.415 + 1.416 +NS_IMETHODIMP 1.417 +nsJARURI::SetPort(int32_t aPort) 1.418 +{ 1.419 + return NS_ERROR_FAILURE; 1.420 +} 1.421 + 1.422 +NS_IMETHODIMP 1.423 +nsJARURI::GetPath(nsACString &aPath) 1.424 +{ 1.425 + nsAutoCString entrySpec; 1.426 + mJAREntry->GetSpec(entrySpec); 1.427 + return FormatSpec(entrySpec, aPath, false); 1.428 +} 1.429 + 1.430 +NS_IMETHODIMP 1.431 +nsJARURI::SetPath(const nsACString &aPath) 1.432 +{ 1.433 + return NS_ERROR_FAILURE; 1.434 +} 1.435 + 1.436 +NS_IMETHODIMP 1.437 +nsJARURI::GetAsciiSpec(nsACString &aSpec) 1.438 +{ 1.439 + // XXX Shouldn't this like... make sure it returns ASCII or something? 1.440 + return GetSpec(aSpec); 1.441 +} 1.442 + 1.443 +NS_IMETHODIMP 1.444 +nsJARURI::GetAsciiHost(nsACString &aHost) 1.445 +{ 1.446 + return NS_ERROR_FAILURE; 1.447 +} 1.448 + 1.449 +NS_IMETHODIMP 1.450 +nsJARURI::GetOriginCharset(nsACString &aOriginCharset) 1.451 +{ 1.452 + aOriginCharset = mCharsetHint; 1.453 + return NS_OK; 1.454 +} 1.455 + 1.456 +NS_IMETHODIMP 1.457 +nsJARURI::Equals(nsIURI *other, bool *result) 1.458 +{ 1.459 + return EqualsInternal(other, eHonorRef, result); 1.460 +} 1.461 + 1.462 +NS_IMETHODIMP 1.463 +nsJARURI::EqualsExceptRef(nsIURI *other, bool *result) 1.464 +{ 1.465 + return EqualsInternal(other, eIgnoreRef, result); 1.466 +} 1.467 + 1.468 +// Helper method: 1.469 +/* virtual */ nsresult 1.470 +nsJARURI::EqualsInternal(nsIURI *other, 1.471 + nsJARURI::RefHandlingEnum refHandlingMode, 1.472 + bool *result) 1.473 +{ 1.474 + *result = false; 1.475 + 1.476 + if (!other) 1.477 + return NS_OK; // not equal 1.478 + 1.479 + nsRefPtr<nsJARURI> otherJAR; 1.480 + other->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR)); 1.481 + if (!otherJAR) 1.482 + return NS_OK; // not equal 1.483 + 1.484 + bool equal; 1.485 + nsresult rv = mJARFile->Equals(otherJAR->mJARFile, &equal); 1.486 + if (NS_FAILED(rv) || !equal) { 1.487 + return rv; // not equal 1.488 + } 1.489 + 1.490 + return refHandlingMode == eHonorRef ? 1.491 + mJAREntry->Equals(otherJAR->mJAREntry, result) : 1.492 + mJAREntry->EqualsExceptRef(otherJAR->mJAREntry, result); 1.493 +} 1.494 + 1.495 +NS_IMETHODIMP 1.496 +nsJARURI::SchemeIs(const char *i_Scheme, bool *o_Equals) 1.497 +{ 1.498 + NS_ENSURE_ARG_POINTER(o_Equals); 1.499 + if (!i_Scheme) return NS_ERROR_INVALID_ARG; 1.500 + 1.501 + if (*i_Scheme == 'j' || *i_Scheme == 'J') { 1.502 + *o_Equals = PL_strcasecmp("jar", i_Scheme) ? false : true; 1.503 + } else { 1.504 + *o_Equals = false; 1.505 + } 1.506 + return NS_OK; 1.507 +} 1.508 + 1.509 +NS_IMETHODIMP 1.510 +nsJARURI::Clone(nsIURI **result) 1.511 +{ 1.512 + nsresult rv; 1.513 + 1.514 + nsCOMPtr<nsIJARURI> uri; 1.515 + rv = CloneWithJARFileInternal(mJARFile, eHonorRef, getter_AddRefs(uri)); 1.516 + if (NS_FAILED(rv)) return rv; 1.517 + 1.518 + return CallQueryInterface(uri, result); 1.519 +} 1.520 + 1.521 +NS_IMETHODIMP 1.522 +nsJARURI::CloneIgnoringRef(nsIURI **result) 1.523 +{ 1.524 + nsresult rv; 1.525 + 1.526 + nsCOMPtr<nsIJARURI> uri; 1.527 + rv = CloneWithJARFileInternal(mJARFile, eIgnoreRef, getter_AddRefs(uri)); 1.528 + if (NS_FAILED(rv)) return rv; 1.529 + 1.530 + return CallQueryInterface(uri, result); 1.531 +} 1.532 + 1.533 +NS_IMETHODIMP 1.534 +nsJARURI::Resolve(const nsACString &relativePath, nsACString &result) 1.535 +{ 1.536 + nsresult rv; 1.537 + 1.538 + nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); 1.539 + if (NS_FAILED(rv)) 1.540 + return rv; 1.541 + 1.542 + nsAutoCString scheme; 1.543 + rv = ioServ->ExtractScheme(relativePath, scheme); 1.544 + if (NS_SUCCEEDED(rv)) { 1.545 + // then aSpec is absolute 1.546 + result = relativePath; 1.547 + return NS_OK; 1.548 + } 1.549 + 1.550 + nsAutoCString resolvedPath; 1.551 + mJAREntry->Resolve(relativePath, resolvedPath); 1.552 + 1.553 + return FormatSpec(resolvedPath, result); 1.554 +} 1.555 + 1.556 +//////////////////////////////////////////////////////////////////////////////// 1.557 +// nsIURL methods: 1.558 + 1.559 +NS_IMETHODIMP 1.560 +nsJARURI::GetFilePath(nsACString& filePath) 1.561 +{ 1.562 + return mJAREntry->GetFilePath(filePath); 1.563 +} 1.564 + 1.565 +NS_IMETHODIMP 1.566 +nsJARURI::SetFilePath(const nsACString& filePath) 1.567 +{ 1.568 + return mJAREntry->SetFilePath(filePath); 1.569 +} 1.570 + 1.571 +NS_IMETHODIMP 1.572 +nsJARURI::GetQuery(nsACString& query) 1.573 +{ 1.574 + return mJAREntry->GetQuery(query); 1.575 +} 1.576 + 1.577 +NS_IMETHODIMP 1.578 +nsJARURI::SetQuery(const nsACString& query) 1.579 +{ 1.580 + return mJAREntry->SetQuery(query); 1.581 +} 1.582 + 1.583 +NS_IMETHODIMP 1.584 +nsJARURI::GetRef(nsACString& ref) 1.585 +{ 1.586 + return mJAREntry->GetRef(ref); 1.587 +} 1.588 + 1.589 +NS_IMETHODIMP 1.590 +nsJARURI::SetRef(const nsACString& ref) 1.591 +{ 1.592 + return mJAREntry->SetRef(ref); 1.593 +} 1.594 + 1.595 +NS_IMETHODIMP 1.596 +nsJARURI::GetDirectory(nsACString& directory) 1.597 +{ 1.598 + return mJAREntry->GetDirectory(directory); 1.599 +} 1.600 + 1.601 +NS_IMETHODIMP 1.602 +nsJARURI::SetDirectory(const nsACString& directory) 1.603 +{ 1.604 + return mJAREntry->SetDirectory(directory); 1.605 +} 1.606 + 1.607 +NS_IMETHODIMP 1.608 +nsJARURI::GetFileName(nsACString& fileName) 1.609 +{ 1.610 + return mJAREntry->GetFileName(fileName); 1.611 +} 1.612 + 1.613 +NS_IMETHODIMP 1.614 +nsJARURI::SetFileName(const nsACString& fileName) 1.615 +{ 1.616 + return mJAREntry->SetFileName(fileName); 1.617 +} 1.618 + 1.619 +NS_IMETHODIMP 1.620 +nsJARURI::GetFileBaseName(nsACString& fileBaseName) 1.621 +{ 1.622 + return mJAREntry->GetFileBaseName(fileBaseName); 1.623 +} 1.624 + 1.625 +NS_IMETHODIMP 1.626 +nsJARURI::SetFileBaseName(const nsACString& fileBaseName) 1.627 +{ 1.628 + return mJAREntry->SetFileBaseName(fileBaseName); 1.629 +} 1.630 + 1.631 +NS_IMETHODIMP 1.632 +nsJARURI::GetFileExtension(nsACString& fileExtension) 1.633 +{ 1.634 + return mJAREntry->GetFileExtension(fileExtension); 1.635 +} 1.636 + 1.637 +NS_IMETHODIMP 1.638 +nsJARURI::SetFileExtension(const nsACString& fileExtension) 1.639 +{ 1.640 + return mJAREntry->SetFileExtension(fileExtension); 1.641 +} 1.642 + 1.643 +NS_IMETHODIMP 1.644 +nsJARURI::GetCommonBaseSpec(nsIURI* uriToCompare, nsACString& commonSpec) 1.645 +{ 1.646 + commonSpec.Truncate(); 1.647 + 1.648 + NS_ENSURE_ARG_POINTER(uriToCompare); 1.649 + 1.650 + commonSpec.Truncate(); 1.651 + nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare)); 1.652 + if (!otherJARURI) { 1.653 + // Nothing in common 1.654 + return NS_OK; 1.655 + } 1.656 + 1.657 + nsCOMPtr<nsIURI> otherJARFile; 1.658 + nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile)); 1.659 + if (NS_FAILED(rv)) return rv; 1.660 + 1.661 + bool equal; 1.662 + rv = mJARFile->Equals(otherJARFile, &equal); 1.663 + if (NS_FAILED(rv)) return rv; 1.664 + 1.665 + if (!equal) { 1.666 + // See what the JAR file URIs have in common 1.667 + nsCOMPtr<nsIURL> ourJARFileURL(do_QueryInterface(mJARFile)); 1.668 + if (!ourJARFileURL) { 1.669 + // Not a URL, so nothing in common 1.670 + return NS_OK; 1.671 + } 1.672 + nsAutoCString common; 1.673 + rv = ourJARFileURL->GetCommonBaseSpec(otherJARFile, common); 1.674 + if (NS_FAILED(rv)) return rv; 1.675 + 1.676 + commonSpec = NS_JAR_SCHEME + common; 1.677 + return NS_OK; 1.678 + 1.679 + } 1.680 + 1.681 + // At this point we have the same JAR file. Compare the JAREntrys 1.682 + nsAutoCString otherEntry; 1.683 + rv = otherJARURI->GetJAREntry(otherEntry); 1.684 + if (NS_FAILED(rv)) return rv; 1.685 + 1.686 + nsAutoCString otherCharset; 1.687 + rv = uriToCompare->GetOriginCharset(otherCharset); 1.688 + if (NS_FAILED(rv)) return rv; 1.689 + 1.690 + nsCOMPtr<nsIURL> url; 1.691 + rv = CreateEntryURL(otherEntry, otherCharset.get(), getter_AddRefs(url)); 1.692 + if (NS_FAILED(rv)) return rv; 1.693 + 1.694 + nsAutoCString common; 1.695 + rv = mJAREntry->GetCommonBaseSpec(url, common); 1.696 + if (NS_FAILED(rv)) return rv; 1.697 + 1.698 + rv = FormatSpec(common, commonSpec); 1.699 + return rv; 1.700 +} 1.701 + 1.702 +NS_IMETHODIMP 1.703 +nsJARURI::GetRelativeSpec(nsIURI* uriToCompare, nsACString& relativeSpec) 1.704 +{ 1.705 + GetSpec(relativeSpec); 1.706 + 1.707 + NS_ENSURE_ARG_POINTER(uriToCompare); 1.708 + 1.709 + nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare)); 1.710 + if (!otherJARURI) { 1.711 + // Nothing in common 1.712 + return NS_OK; 1.713 + } 1.714 + 1.715 + nsCOMPtr<nsIURI> otherJARFile; 1.716 + nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile)); 1.717 + if (NS_FAILED(rv)) return rv; 1.718 + 1.719 + bool equal; 1.720 + rv = mJARFile->Equals(otherJARFile, &equal); 1.721 + if (NS_FAILED(rv)) return rv; 1.722 + 1.723 + if (!equal) { 1.724 + // We live in different JAR files. Nothing in common. 1.725 + return rv; 1.726 + } 1.727 + 1.728 + // Same JAR file. Compare the JAREntrys 1.729 + nsAutoCString otherEntry; 1.730 + rv = otherJARURI->GetJAREntry(otherEntry); 1.731 + if (NS_FAILED(rv)) return rv; 1.732 + 1.733 + nsAutoCString otherCharset; 1.734 + rv = uriToCompare->GetOriginCharset(otherCharset); 1.735 + if (NS_FAILED(rv)) return rv; 1.736 + 1.737 + nsCOMPtr<nsIURL> url; 1.738 + rv = CreateEntryURL(otherEntry, otherCharset.get(), getter_AddRefs(url)); 1.739 + if (NS_FAILED(rv)) return rv; 1.740 + 1.741 + nsAutoCString relativeEntrySpec; 1.742 + rv = mJAREntry->GetRelativeSpec(url, relativeEntrySpec); 1.743 + if (NS_FAILED(rv)) return rv; 1.744 + 1.745 + if (!StringBeginsWith(relativeEntrySpec, NS_BOGUS_ENTRY_SCHEME)) { 1.746 + // An actual relative spec! 1.747 + relativeSpec = relativeEntrySpec; 1.748 + } 1.749 + return rv; 1.750 +} 1.751 + 1.752 +//////////////////////////////////////////////////////////////////////////////// 1.753 +// nsIJARURI methods: 1.754 + 1.755 +NS_IMETHODIMP 1.756 +nsJARURI::GetJARFile(nsIURI* *jarFile) 1.757 +{ 1.758 + return GetInnerURI(jarFile); 1.759 +} 1.760 + 1.761 +NS_IMETHODIMP 1.762 +nsJARURI::GetJAREntry(nsACString &entryPath) 1.763 +{ 1.764 + nsAutoCString filePath; 1.765 + mJAREntry->GetFilePath(filePath); 1.766 + NS_ASSERTION(filePath.Length() > 0, "path should never be empty!"); 1.767 + // Trim off the leading '/' 1.768 + entryPath = Substring(filePath, 1, filePath.Length() - 1); 1.769 + return NS_OK; 1.770 +} 1.771 + 1.772 +NS_IMETHODIMP 1.773 +nsJARURI::SetJAREntry(const nsACString &entryPath) 1.774 +{ 1.775 + return CreateEntryURL(entryPath, mCharsetHint.get(), 1.776 + getter_AddRefs(mJAREntry)); 1.777 +} 1.778 + 1.779 +NS_IMETHODIMP 1.780 +nsJARURI::CloneWithJARFile(nsIURI *jarFile, nsIJARURI **result) 1.781 +{ 1.782 + return CloneWithJARFileInternal(jarFile, eHonorRef, result); 1.783 +} 1.784 + 1.785 +nsresult 1.786 +nsJARURI::CloneWithJARFileInternal(nsIURI *jarFile, 1.787 + nsJARURI::RefHandlingEnum refHandlingMode, 1.788 + nsIJARURI **result) 1.789 +{ 1.790 + if (!jarFile) { 1.791 + return NS_ERROR_INVALID_ARG; 1.792 + } 1.793 + 1.794 + nsresult rv; 1.795 + 1.796 + nsCOMPtr<nsIURI> newJARFile; 1.797 + rv = jarFile->Clone(getter_AddRefs(newJARFile)); 1.798 + if (NS_FAILED(rv)) return rv; 1.799 + 1.800 + NS_TryToSetImmutable(newJARFile); 1.801 + 1.802 + nsCOMPtr<nsIURI> newJAREntryURI; 1.803 + rv = refHandlingMode == eHonorRef ? 1.804 + mJAREntry->Clone(getter_AddRefs(newJAREntryURI)) : 1.805 + mJAREntry->CloneIgnoringRef(getter_AddRefs(newJAREntryURI)); 1.806 + 1.807 + if (NS_FAILED(rv)) return rv; 1.808 + 1.809 + nsCOMPtr<nsIURL> newJAREntry(do_QueryInterface(newJAREntryURI)); 1.810 + NS_ASSERTION(newJAREntry, "This had better QI to nsIURL!"); 1.811 + 1.812 + nsJARURI* uri = new nsJARURI(); 1.813 + NS_ADDREF(uri); 1.814 + uri->mJARFile = newJARFile; 1.815 + uri->mJAREntry = newJAREntry; 1.816 + *result = uri; 1.817 + 1.818 + return NS_OK; 1.819 +} 1.820 + 1.821 +//////////////////////////////////////////////////////////////////////////////// 1.822 + 1.823 +NS_IMETHODIMP 1.824 +nsJARURI::GetInnerURI(nsIURI **uri) 1.825 +{ 1.826 + return NS_EnsureSafeToReturn(mJARFile, uri); 1.827 +} 1.828 + 1.829 +NS_IMETHODIMP 1.830 +nsJARURI::GetInnermostURI(nsIURI** uri) 1.831 +{ 1.832 + return NS_ImplGetInnermostURI(this, uri); 1.833 +} 1.834 + 1.835 +//////////////////////////////////////////////////////////////////////////////// 1.836 +// nsIIPCSerializableURI methods: 1.837 + 1.838 +void 1.839 +nsJARURI::Serialize(URIParams& aParams) 1.840 +{ 1.841 + JARURIParams params; 1.842 + 1.843 + SerializeURI(mJARFile, params.jarFile()); 1.844 + SerializeURI(mJAREntry, params.jarEntry()); 1.845 + params.charset() = mCharsetHint; 1.846 + 1.847 + aParams = params; 1.848 +} 1.849 + 1.850 +bool 1.851 +nsJARURI::Deserialize(const URIParams& aParams) 1.852 +{ 1.853 + if (aParams.type() != URIParams::TJARURIParams) { 1.854 + NS_ERROR("Received unknown parameters from the other process!"); 1.855 + return false; 1.856 + } 1.857 + 1.858 + const JARURIParams& params = aParams.get_JARURIParams(); 1.859 + 1.860 + nsCOMPtr<nsIURI> file = DeserializeURI(params.jarFile()); 1.861 + if (!file) { 1.862 + NS_ERROR("Couldn't deserialize jar file URI!"); 1.863 + return false; 1.864 + } 1.865 + 1.866 + nsCOMPtr<nsIURI> entry = DeserializeURI(params.jarEntry()); 1.867 + if (!entry) { 1.868 + NS_ERROR("Couldn't deserialize jar entry URI!"); 1.869 + return false; 1.870 + } 1.871 + 1.872 + nsCOMPtr<nsIURL> entryURL = do_QueryInterface(entry); 1.873 + if (!entryURL) { 1.874 + NS_ERROR("Couldn't QI jar entry URI to nsIURL!"); 1.875 + return false; 1.876 + } 1.877 + 1.878 + mJARFile.swap(file); 1.879 + mJAREntry.swap(entryURL); 1.880 + mCharsetHint = params.charset(); 1.881 + 1.882 + return true; 1.883 +}