nsJARURI.cpp (20038B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "base/basictypes.h" 8 9 #include "nsJARURI.h" 10 #include "nsNetUtil.h" 11 #include "nsIClassInfoImpl.h" 12 #include "nsIIOService.h" 13 #include "nsIStandardURL.h" 14 #include "nsCRT.h" 15 #include "nsReadableUtils.h" 16 #include "nsNetCID.h" 17 #include "nsIObjectInputStream.h" 18 #include "nsIObjectOutputStream.h" 19 #include "nsQueryObject.h" 20 #include "mozilla/ipc/URIUtils.h" 21 22 using namespace mozilla::ipc; 23 24 //////////////////////////////////////////////////////////////////////////////// 25 26 NS_IMPL_CLASSINFO(nsJARURI, nullptr, nsIClassInfo::THREADSAFE, NS_JARURI_CID) 27 // Empty CI getter. We only need nsIClassInfo for Serialization 28 NS_IMPL_CI_INTERFACE_GETTER0(nsJARURI) 29 30 nsJARURI::nsJARURI() {} 31 32 nsJARURI::~nsJARURI() {} 33 34 // XXX Why is this threadsafe? 35 NS_IMPL_ADDREF(nsJARURI) 36 NS_IMPL_RELEASE(nsJARURI) 37 NS_INTERFACE_MAP_BEGIN(nsJARURI) 38 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJARURI) 39 NS_INTERFACE_MAP_ENTRY(nsIURI) 40 NS_INTERFACE_MAP_ENTRY(nsIURL) 41 NS_INTERFACE_MAP_ENTRY(nsIJARURI) 42 NS_INTERFACE_MAP_ENTRY(nsISerializable) 43 NS_IMPL_QUERY_CLASSINFO(nsJARURI) 44 NS_INTERFACE_MAP_ENTRY(nsINestedURI) 45 NS_INTERFACE_MAP_ENTRY_CONCRETE(nsJARURI) 46 NS_INTERFACE_MAP_END 47 48 nsresult nsJARURI::Init(const char* charsetHint) { 49 mCharsetHint = charsetHint; 50 return NS_OK; 51 } 52 53 #define NS_JAR_SCHEME "jar:"_ns 54 #define NS_JAR_DELIMITER "!/"_ns 55 #define NS_BOGUS_ENTRY_SCHEME "x:///"_ns 56 57 // FormatSpec takes the entry spec (including the "x:///" at the 58 // beginning) and gives us a full JAR spec. 59 nsresult nsJARURI::FormatSpec(const nsACString& entrySpec, nsACString& result, 60 bool aIncludeScheme) { 61 // The entrySpec MUST start with "x:///" 62 NS_ASSERTION(StringBeginsWith(entrySpec, NS_BOGUS_ENTRY_SCHEME), 63 "bogus entry spec"); 64 65 nsAutoCString fileSpec; 66 nsresult rv = mJARFile->GetSpec(fileSpec); 67 if (NS_FAILED(rv)) return rv; 68 69 if (aIncludeScheme) 70 result = NS_JAR_SCHEME; 71 else 72 result.Truncate(); 73 74 result.Append(fileSpec + NS_JAR_DELIMITER + 75 Substring(entrySpec, 5, entrySpec.Length() - 5)); 76 return NS_OK; 77 } 78 79 nsresult nsJARURI::CreateEntryURL(const nsACString& entryFilename, 80 const char* charset, nsIURL** url) { 81 *url = nullptr; 82 // Flatten the concatenation, just in case. See bug 128288 83 nsAutoCString spec(NS_BOGUS_ENTRY_SCHEME + entryFilename); 84 return NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) 85 .Apply(&nsIStandardURLMutator::Init, nsIStandardURL::URLTYPE_NO_AUTHORITY, 86 -1, spec, charset, nullptr, nullptr) 87 .Finalize(url); 88 } 89 90 //////////////////////////////////////////////////////////////////////////////// 91 // nsISerializable methods: 92 93 NS_IMETHODIMP 94 nsJARURI::Read(nsIObjectInputStream* aStream) { 95 MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead"); 96 return NS_ERROR_NOT_IMPLEMENTED; 97 } 98 99 nsresult nsJARURI::ReadPrivate(nsIObjectInputStream* aInputStream) { 100 nsresult rv; 101 102 nsCOMPtr<nsISupports> supports; 103 rv = aInputStream->ReadObject(true, getter_AddRefs(supports)); 104 NS_ENSURE_SUCCESS(rv, rv); 105 106 mJARFile = do_QueryInterface(supports, &rv); 107 NS_ENSURE_SUCCESS(rv, rv); 108 109 rv = aInputStream->ReadObject(true, getter_AddRefs(supports)); 110 NS_ENSURE_SUCCESS(rv, rv); 111 112 mJAREntry = do_QueryInterface(supports); 113 NS_ENSURE_SUCCESS(rv, rv); 114 115 rv = aInputStream->ReadCString(mCharsetHint); 116 return rv; 117 } 118 119 NS_IMETHODIMP 120 nsJARURI::Write(nsIObjectOutputStream* aOutputStream) { 121 nsresult rv; 122 123 rv = aOutputStream->WriteCompoundObject(mJARFile, NS_GET_IID(nsIURI), true); 124 NS_ENSURE_SUCCESS(rv, rv); 125 126 rv = aOutputStream->WriteCompoundObject(mJAREntry, NS_GET_IID(nsIURL), true); 127 NS_ENSURE_SUCCESS(rv, rv); 128 129 rv = aOutputStream->WriteStringZ(mCharsetHint.get()); 130 return rv; 131 } 132 133 //////////////////////////////////////////////////////////////////////////////// 134 // nsIURI methods: 135 136 NS_IMETHODIMP 137 nsJARURI::GetSpec(nsACString& aSpec) { 138 nsAutoCString entrySpec; 139 mJAREntry->GetSpec(entrySpec); 140 return FormatSpec(entrySpec, aSpec); 141 } 142 143 NS_IMETHODIMP 144 nsJARURI::GetSpecIgnoringRef(nsACString& aSpec) { 145 nsAutoCString entrySpec; 146 mJAREntry->GetSpecIgnoringRef(entrySpec); 147 return FormatSpec(entrySpec, aSpec); 148 } 149 150 NS_IMETHODIMP 151 nsJARURI::GetDisplaySpec(nsACString& aUnicodeSpec) { 152 return GetSpec(aUnicodeSpec); 153 } 154 155 NS_IMETHODIMP 156 nsJARURI::GetDisplayHostPort(nsACString& aUnicodeHostPort) { 157 return GetHostPort(aUnicodeHostPort); 158 } 159 160 NS_IMETHODIMP 161 nsJARURI::GetDisplayPrePath(nsACString& aPrePath) { 162 return GetPrePath(aPrePath); 163 } 164 165 NS_IMETHODIMP 166 nsJARURI::GetDisplayHost(nsACString& aUnicodeHost) { 167 return GetHost(aUnicodeHost); 168 } 169 170 NS_IMETHODIMP 171 nsJARURI::GetHasRef(bool* result) { return mJAREntry->GetHasRef(result); } 172 173 NS_IMETHODIMP 174 nsJARURI::GetHasUserPass(bool* result) { 175 return mJAREntry->GetHasUserPass(result); 176 } 177 178 NS_IMETHODIMP 179 nsJARURI::GetHasQuery(bool* result) { return mJAREntry->GetHasQuery(result); } 180 181 nsresult nsJARURI::SetSpecInternal(const nsACString& aSpec) { 182 return SetSpecWithBase(aSpec, nullptr); 183 } 184 185 // Queries this list of interfaces. If none match, it queries mURI. 186 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsJARURI::Mutator, nsIURISetters, nsIURIMutator, 187 nsIURLMutator, nsISerializable, 188 nsIJARURIMutator) 189 190 NS_IMETHODIMP 191 nsJARURI::Mutator::SetFileName(const nsACString& aFileName, 192 nsIURIMutator** aMutator) { 193 if (!mURI) { 194 return NS_ERROR_NULL_POINTER; 195 } 196 if (aMutator) { 197 nsCOMPtr<nsIURIMutator> mutator = this; 198 mutator.forget(aMutator); 199 } 200 return mURI->SetFileNameInternal(aFileName); 201 } 202 203 NS_IMETHODIMP 204 nsJARURI::Mutator::SetFileBaseName(const nsACString& aFileBaseName, 205 nsIURIMutator** aMutator) { 206 if (!mURI) { 207 return NS_ERROR_NULL_POINTER; 208 } 209 if (aMutator) { 210 nsCOMPtr<nsIURIMutator> mutator = this; 211 mutator.forget(aMutator); 212 } 213 return mURI->SetFileBaseNameInternal(aFileBaseName); 214 } 215 216 NS_IMETHODIMP 217 nsJARURI::Mutator::SetFileExtension(const nsACString& aFileExtension, 218 nsIURIMutator** aMutator) { 219 if (!mURI) { 220 return NS_ERROR_NULL_POINTER; 221 } 222 if (aMutator) { 223 nsCOMPtr<nsIURIMutator> mutator = this; 224 mutator.forget(aMutator); 225 } 226 return mURI->SetFileExtensionInternal(aFileExtension); 227 } 228 229 NS_IMETHODIMP 230 nsJARURI::Mutate(nsIURIMutator** aMutator) { 231 RefPtr<nsJARURI::Mutator> mutator = new nsJARURI::Mutator(); 232 nsresult rv = mutator->InitFromURI(this); 233 if (NS_FAILED(rv)) { 234 return rv; 235 } 236 mutator.forget(aMutator); 237 return NS_OK; 238 } 239 240 nsresult nsJARURI::SetSpecWithBase(const nsACString& aSpec, nsIURI* aBaseURL) { 241 nsresult rv; 242 243 nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); 244 NS_ENSURE_SUCCESS(rv, rv); 245 246 nsAutoCString scheme; 247 rv = ioServ->ExtractScheme(aSpec, scheme); 248 if (NS_FAILED(rv)) { 249 // not an absolute URI 250 if (!aBaseURL) return NS_ERROR_MALFORMED_URI; 251 252 RefPtr<nsJARURI> otherJAR = do_QueryObject(aBaseURL); 253 NS_ENSURE_TRUE(otherJAR, NS_NOINTERFACE); 254 255 mJARFile = otherJAR->mJARFile; 256 257 nsCOMPtr<nsIURI> entry; 258 259 rv = NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID) 260 .Apply(&nsIStandardURLMutator::Init, 261 nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, aSpec, 262 mCharsetHint.get(), otherJAR->mJAREntry, nullptr) 263 .Finalize(entry); 264 if (NS_FAILED(rv)) { 265 return rv; 266 } 267 268 mJAREntry = do_QueryInterface(entry); 269 if (!mJAREntry) return NS_NOINTERFACE; 270 271 return NS_OK; 272 } 273 274 NS_ENSURE_TRUE(scheme.EqualsLiteral("jar"), NS_ERROR_MALFORMED_URI); 275 276 nsACString::const_iterator begin, end; 277 aSpec.BeginReading(begin); 278 aSpec.EndReading(end); 279 280 while (begin != end && *begin != ':') ++begin; 281 282 ++begin; // now we're past the "jar:" 283 284 nsACString::const_iterator delim_begin = begin; 285 nsACString::const_iterator delim_end = end; 286 nsACString::const_iterator frag = begin; 287 288 if (FindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end)) { 289 frag = delim_end; 290 } 291 while (frag != end && (*frag != '#' && *frag != '?')) { 292 ++frag; 293 } 294 if (frag != end) { 295 // there was a fragment or query, mark that as the end of the URL to scan 296 end = frag; 297 } 298 299 // Search backward from the end for the "!/" delimiter. Remember, jar URLs 300 // can nest, e.g.: 301 // jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html 302 // This gets the b.html document from out of the a.jar file, that's 303 // contained within the bar.jar file. 304 // Also, the outermost "inner" URI may be a relative URI: 305 // jar:../relative.jar!/a.html 306 307 delim_begin = begin; 308 delim_end = end; 309 310 if (!RFindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end)) { 311 return NS_ERROR_MALFORMED_URI; 312 } 313 314 rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(), 315 aBaseURL, getter_AddRefs(mJARFile)); 316 if (NS_FAILED(rv)) return rv; 317 318 // skip over any extra '/' chars 319 while (*delim_end == '/') ++delim_end; 320 321 aSpec.EndReading(end); // set to the original 'end' 322 return SetJAREntry(Substring(delim_end, end)); 323 } 324 325 NS_IMETHODIMP 326 nsJARURI::GetPrePath(nsACString& prePath) { 327 prePath = NS_JAR_SCHEME; 328 return NS_OK; 329 } 330 331 NS_IMETHODIMP 332 nsJARURI::GetScheme(nsACString& aScheme) { 333 aScheme = "jar"; 334 return NS_OK; 335 } 336 337 nsresult nsJARURI::SetScheme(const nsACString& aScheme) { 338 // doesn't make sense to set the scheme of a jar: URL 339 return NS_ERROR_FAILURE; 340 } 341 342 NS_IMETHODIMP 343 nsJARURI::GetUserPass(nsACString& aUserPass) { return NS_ERROR_FAILURE; } 344 345 nsresult nsJARURI::SetUserPass(const nsACString& aUserPass) { 346 return NS_ERROR_FAILURE; 347 } 348 349 NS_IMETHODIMP 350 nsJARURI::GetUsername(nsACString& aUsername) { return NS_ERROR_FAILURE; } 351 352 nsresult nsJARURI::SetUsername(const nsACString& aUsername) { 353 return NS_ERROR_FAILURE; 354 } 355 356 NS_IMETHODIMP 357 nsJARURI::GetPassword(nsACString& aPassword) { return NS_ERROR_FAILURE; } 358 359 nsresult nsJARURI::SetPassword(const nsACString& aPassword) { 360 return NS_ERROR_FAILURE; 361 } 362 363 NS_IMETHODIMP 364 nsJARURI::GetHostPort(nsACString& aHostPort) { return NS_ERROR_FAILURE; } 365 366 nsresult nsJARURI::SetHostPort(const nsACString& aHostPort) { 367 return NS_ERROR_FAILURE; 368 } 369 370 NS_IMETHODIMP 371 nsJARURI::GetHost(nsACString& aHost) { return NS_ERROR_FAILURE; } 372 373 nsresult nsJARURI::SetHost(const nsACString& aHost) { return NS_ERROR_FAILURE; } 374 375 NS_IMETHODIMP 376 nsJARURI::GetPort(int32_t* aPort) { return NS_ERROR_FAILURE; } 377 378 nsresult nsJARURI::SetPort(int32_t aPort) { return NS_ERROR_FAILURE; } 379 380 nsresult nsJARURI::GetPathQueryRef(nsACString& aPath) { 381 nsAutoCString entrySpec; 382 mJAREntry->GetSpec(entrySpec); 383 return FormatSpec(entrySpec, aPath, false); 384 } 385 386 nsresult nsJARURI::SetPathQueryRef(const nsACString& aPath) { 387 return NS_ERROR_FAILURE; 388 } 389 390 NS_IMETHODIMP 391 nsJARURI::GetAsciiSpec(nsACString& aSpec) { 392 // XXX Shouldn't this like... make sure it returns ASCII or something? 393 return GetSpec(aSpec); 394 } 395 396 NS_IMETHODIMP 397 nsJARURI::GetAsciiHostPort(nsACString& aHostPort) { return NS_ERROR_FAILURE; } 398 399 NS_IMETHODIMP 400 nsJARURI::GetAsciiHost(nsACString& aHost) { return NS_ERROR_FAILURE; } 401 402 NS_IMETHODIMP 403 nsJARURI::Equals(nsIURI* other, bool* result) { 404 return EqualsInternal(other, eHonorRef, result); 405 } 406 407 NS_IMETHODIMP 408 nsJARURI::EqualsExceptRef(nsIURI* other, bool* result) { 409 return EqualsInternal(other, eIgnoreRef, result); 410 } 411 412 // Helper method: 413 /* virtual */ 414 nsresult nsJARURI::EqualsInternal(nsIURI* other, 415 nsJARURI::RefHandlingEnum refHandlingMode, 416 bool* result) { 417 *result = false; 418 419 if (!other) return NS_OK; // not equal 420 421 RefPtr<nsJARURI> otherJAR = do_QueryObject(other); 422 if (!otherJAR) return NS_OK; // not equal 423 424 bool equal; 425 nsresult rv = mJARFile->Equals(otherJAR->mJARFile, &equal); 426 if (NS_FAILED(rv) || !equal) { 427 return rv; // not equal 428 } 429 430 return refHandlingMode == eHonorRef 431 ? mJAREntry->Equals(otherJAR->mJAREntry, result) 432 : mJAREntry->EqualsExceptRef(otherJAR->mJAREntry, result); 433 } 434 435 NS_IMETHODIMP 436 nsJARURI::SchemeIs(const char* i_Scheme, bool* o_Equals) { 437 MOZ_ASSERT(o_Equals); 438 if (!i_Scheme) { 439 *o_Equals = false; 440 return NS_OK; 441 } 442 443 *o_Equals = nsCRT::strcasecmp("jar", i_Scheme) == 0; 444 return NS_OK; 445 } 446 447 nsresult nsJARURI::Clone(nsIURI** result) { 448 RefPtr<nsJARURI> uri = new nsJARURI(); 449 uri->mJARFile = mJARFile; 450 uri->mJAREntry = mJAREntry; 451 uri.forget(result); 452 453 return NS_OK; 454 } 455 456 NS_IMETHODIMP 457 nsJARURI::Resolve(const nsACString& relativePath, nsACString& result) { 458 nsresult rv; 459 460 nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv)); 461 if (NS_FAILED(rv)) return rv; 462 463 nsAutoCString scheme; 464 rv = ioServ->ExtractScheme(relativePath, scheme); 465 if (NS_SUCCEEDED(rv)) { 466 // then aSpec is absolute 467 result = relativePath; 468 return NS_OK; 469 } 470 471 nsAutoCString resolvedPath; 472 mJAREntry->Resolve(relativePath, resolvedPath); 473 474 return FormatSpec(resolvedPath, result); 475 } 476 477 //////////////////////////////////////////////////////////////////////////////// 478 // nsIURL methods: 479 480 NS_IMETHODIMP 481 nsJARURI::GetFilePath(nsACString& filePath) { 482 return mJAREntry->GetFilePath(filePath); 483 } 484 485 nsresult nsJARURI::SetFilePath(const nsACString& filePath) { 486 return NS_MutateURI(mJAREntry).SetFilePath(filePath).Finalize(mJAREntry); 487 } 488 489 NS_IMETHODIMP 490 nsJARURI::GetQuery(nsACString& query) { return mJAREntry->GetQuery(query); } 491 492 nsresult nsJARURI::SetQuery(const nsACString& query) { 493 return NS_MutateURI(mJAREntry).SetQuery(query).Finalize(mJAREntry); 494 } 495 496 nsresult nsJARURI::SetQueryWithEncoding(const nsACString& query, 497 const mozilla::Encoding* encoding) { 498 return NS_MutateURI(mJAREntry) 499 .SetQueryWithEncoding(query, encoding) 500 .Finalize(mJAREntry); 501 } 502 503 NS_IMETHODIMP 504 nsJARURI::GetRef(nsACString& ref) { return mJAREntry->GetRef(ref); } 505 506 nsresult nsJARURI::SetRef(const nsACString& ref) { 507 return NS_MutateURI(mJAREntry).SetRef(ref).Finalize(mJAREntry); 508 } 509 510 NS_IMETHODIMP 511 nsJARURI::GetDirectory(nsACString& directory) { 512 return mJAREntry->GetDirectory(directory); 513 } 514 515 NS_IMETHODIMP 516 nsJARURI::GetFileName(nsACString& fileName) { 517 return mJAREntry->GetFileName(fileName); 518 } 519 520 nsresult nsJARURI::SetFileNameInternal(const nsACString& fileName) { 521 return NS_MutateURI(mJAREntry) 522 .Apply(&nsIURLMutator::SetFileName, fileName, nullptr) 523 .Finalize(mJAREntry); 524 } 525 526 NS_IMETHODIMP 527 nsJARURI::GetFileBaseName(nsACString& fileBaseName) { 528 return mJAREntry->GetFileBaseName(fileBaseName); 529 } 530 531 nsresult nsJARURI::SetFileBaseNameInternal(const nsACString& fileBaseName) { 532 return NS_MutateURI(mJAREntry) 533 .Apply(&nsIURLMutator::SetFileBaseName, fileBaseName, nullptr) 534 .Finalize(mJAREntry); 535 } 536 537 NS_IMETHODIMP 538 nsJARURI::GetFileExtension(nsACString& fileExtension) { 539 return mJAREntry->GetFileExtension(fileExtension); 540 } 541 542 nsresult nsJARURI::SetFileExtensionInternal(const nsACString& fileExtension) { 543 return NS_MutateURI(mJAREntry) 544 .Apply(&nsIURLMutator::SetFileExtension, fileExtension, nullptr) 545 .Finalize(mJAREntry); 546 } 547 548 NS_IMETHODIMP 549 nsJARURI::GetCommonBaseSpec(nsIURI* uriToCompare, nsACString& commonSpec) { 550 commonSpec.Truncate(); 551 552 NS_ENSURE_ARG_POINTER(uriToCompare); 553 554 commonSpec.Truncate(); 555 nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare)); 556 if (!otherJARURI) { 557 // Nothing in common 558 return NS_OK; 559 } 560 561 nsCOMPtr<nsIURI> otherJARFile; 562 nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile)); 563 if (NS_FAILED(rv)) return rv; 564 565 bool equal; 566 rv = mJARFile->Equals(otherJARFile, &equal); 567 if (NS_FAILED(rv)) return rv; 568 569 if (!equal) { 570 // See what the JAR file URIs have in common 571 nsCOMPtr<nsIURL> ourJARFileURL(do_QueryInterface(mJARFile)); 572 if (!ourJARFileURL) { 573 // Not a URL, so nothing in common 574 return NS_OK; 575 } 576 nsAutoCString common; 577 rv = ourJARFileURL->GetCommonBaseSpec(otherJARFile, common); 578 if (NS_FAILED(rv)) return rv; 579 580 commonSpec = NS_JAR_SCHEME + common; 581 return NS_OK; 582 } 583 584 // At this point we have the same JAR file. Compare the JAREntrys 585 nsAutoCString otherEntry; 586 rv = otherJARURI->GetJAREntry(otherEntry); 587 if (NS_FAILED(rv)) return rv; 588 589 nsCOMPtr<nsIURL> url; 590 rv = CreateEntryURL(otherEntry, nullptr, getter_AddRefs(url)); 591 if (NS_FAILED(rv)) return rv; 592 593 nsAutoCString common; 594 rv = mJAREntry->GetCommonBaseSpec(url, common); 595 if (NS_FAILED(rv)) return rv; 596 597 rv = FormatSpec(common, commonSpec); 598 return rv; 599 } 600 601 NS_IMETHODIMP 602 nsJARURI::GetRelativeSpec(nsIURI* uriToCompare, nsACString& relativeSpec) { 603 GetSpec(relativeSpec); 604 605 NS_ENSURE_ARG_POINTER(uriToCompare); 606 607 nsCOMPtr<nsIJARURI> otherJARURI(do_QueryInterface(uriToCompare)); 608 if (!otherJARURI) { 609 // Nothing in common 610 return NS_OK; 611 } 612 613 nsCOMPtr<nsIURI> otherJARFile; 614 nsresult rv = otherJARURI->GetJARFile(getter_AddRefs(otherJARFile)); 615 if (NS_FAILED(rv)) return rv; 616 617 bool equal; 618 rv = mJARFile->Equals(otherJARFile, &equal); 619 if (NS_FAILED(rv)) return rv; 620 621 if (!equal) { 622 // We live in different JAR files. Nothing in common. 623 return rv; 624 } 625 626 // Same JAR file. Compare the JAREntrys 627 nsAutoCString otherEntry; 628 rv = otherJARURI->GetJAREntry(otherEntry); 629 if (NS_FAILED(rv)) return rv; 630 631 nsCOMPtr<nsIURL> url; 632 rv = CreateEntryURL(otherEntry, nullptr, getter_AddRefs(url)); 633 if (NS_FAILED(rv)) return rv; 634 635 nsAutoCString relativeEntrySpec; 636 rv = mJAREntry->GetRelativeSpec(url, relativeEntrySpec); 637 if (NS_FAILED(rv)) return rv; 638 639 if (!StringBeginsWith(relativeEntrySpec, NS_BOGUS_ENTRY_SCHEME)) { 640 // An actual relative spec! 641 relativeSpec = relativeEntrySpec; 642 } 643 return rv; 644 } 645 646 //////////////////////////////////////////////////////////////////////////////// 647 // nsIJARURI methods: 648 649 NS_IMETHODIMP 650 nsJARURI::GetJARFile(nsIURI** jarFile) { return GetInnerURI(jarFile); } 651 652 NS_IMETHODIMP 653 nsJARURI::GetJAREntry(nsACString& entryPath) { 654 nsAutoCString filePath; 655 mJAREntry->GetFilePath(filePath); 656 NS_ASSERTION(filePath.Length() > 0, "path should never be empty!"); 657 // Trim off the leading '/' 658 entryPath = Substring(filePath, 1, filePath.Length() - 1); 659 return NS_OK; 660 } 661 662 nsresult nsJARURI::SetJAREntry(const nsACString& entryPath) { 663 return CreateEntryURL(entryPath, mCharsetHint.get(), 664 getter_AddRefs(mJAREntry)); 665 } 666 667 //////////////////////////////////////////////////////////////////////////////// 668 669 NS_IMETHODIMP 670 nsJARURI::GetInnerURI(nsIURI** aURI) { 671 nsCOMPtr<nsIURI> uri = mJARFile; 672 uri.forget(aURI); 673 return NS_OK; 674 } 675 676 NS_IMETHODIMP 677 nsJARURI::GetInnermostURI(nsIURI** uri) { 678 return NS_ImplGetInnermostURI(this, uri); 679 } 680 681 void nsJARURI::Serialize(URIParams& aParams) { 682 JARURIParams params; 683 684 SerializeURI(mJARFile, params.jarFile()); 685 SerializeURI(mJAREntry, params.jarEntry()); 686 params.charset() = mCharsetHint; 687 688 aParams = params; 689 } 690 691 bool nsJARURI::Deserialize(const URIParams& aParams) { 692 if (aParams.type() != URIParams::TJARURIParams) { 693 NS_ERROR("Received unknown parameters from the other process!"); 694 return false; 695 } 696 697 const JARURIParams& params = aParams.get_JARURIParams(); 698 699 nsCOMPtr<nsIURI> file = DeserializeURI(params.jarFile()); 700 if (!file) { 701 NS_ERROR("Couldn't deserialize jar file URI!"); 702 return false; 703 } 704 705 nsCOMPtr<nsIURI> entry = DeserializeURI(params.jarEntry()); 706 if (!entry) { 707 NS_ERROR("Couldn't deserialize jar entry URI!"); 708 return false; 709 } 710 711 nsCOMPtr<nsIURL> entryURL = do_QueryInterface(entry); 712 if (!entryURL) { 713 NS_ERROR("Couldn't QI jar entry URI to nsIURL!"); 714 return false; 715 } 716 717 mJARFile.swap(file); 718 mJAREntry.swap(entryURL); 719 mCharsetHint = params.charset(); 720 721 return true; 722 } 723 724 size_t nsJARURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) { 725 // We don't need to calculate this unless it shows up in DMD. 726 return 0; 727 };