diff --git a/mozilla/modules/libjar/nsJARProtocolHandler.cpp b/mozilla/modules/libjar/nsJARProtocolHandler.cpp index e11a7e96027..f279d73ba57 100644 --- a/mozilla/modules/libjar/nsJARProtocolHandler.cpp +++ b/mozilla/modules/libjar/nsJARProtocolHandler.cpp @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Benjamin Smedberg * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -35,6 +36,7 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsAutoPtr.h" #include "nsJARProtocolHandler.h" #include "nsIIOService.h" #include "nsCRT.h" @@ -153,35 +155,19 @@ nsJARProtocolHandler::NewURI(const nsACString &aSpec, nsIURI **result) { nsresult rv = NS_OK; - nsIURI* url; - nsJARURI *jarURI = new nsJARURI(); + nsRefPtr jarURI = new nsJARURI(); if (!jarURI) return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(url = jarURI); - rv = jarURI->Init(aCharset); - if (NS_FAILED(rv)) { - NS_RELEASE(url); + NS_ENSURE_SUCCESS(rv, rv); + + rv = jarURI->SetSpecWithBase(aSpec, aBaseURI); + if (NS_FAILED(rv)) return rv; - } - if (aBaseURI) { - nsCAutoString aResolvedURI; - rv = aBaseURI->Resolve(aSpec, aResolvedURI); - if (NS_FAILED(rv)) return rv; - rv = url->SetSpec(aResolvedURI); - } - else - rv = url->SetSpec(aSpec); - - if (NS_FAILED(rv)) { - NS_RELEASE(url); - return rv; - } - - *result = url; + NS_ADDREF(*result = jarURI); return rv; } diff --git a/mozilla/modules/libjar/nsJARURI.cpp b/mozilla/modules/libjar/nsJARURI.cpp index 6fe8b207004..1c29666f9ac 100644 --- a/mozilla/modules/libjar/nsJARURI.cpp +++ b/mozilla/modules/libjar/nsJARURI.cpp @@ -52,8 +52,6 @@ static NS_DEFINE_CID(kJARURICID, NS_JARURI_CID); -static NS_DEFINE_CID(kThisImplCID, NS_THIS_JARURI_IMPL_CID); - //////////////////////////////////////////////////////////////////////////////// nsJARURI::nsJARURI() @@ -75,8 +73,8 @@ NS_INTERFACE_MAP_BEGIN(nsJARURI) NS_INTERFACE_MAP_ENTRY(nsISerializable) NS_INTERFACE_MAP_ENTRY(nsIClassInfo) // see nsJARURI::Equals - if (aIID.Equals(kThisImplCID)) - foundInterface = NS_STATIC_CAST(nsIJARURI *, this); + if (aIID.Equals(NS_GET_IID(nsJARURI))) + foundInterface = NS_REINTERPRET_CAST(nsISupports*, this); else NS_INTERFACE_MAP_END @@ -248,38 +246,75 @@ nsJARURI::GetSpec(nsACString &aSpec) } NS_IMETHODIMP -nsJARURI::SetSpec(const nsACString &aSpec) +nsJARURI::SetSpec(const nsACString& aSpec) +{ + return SetSpecWithBase(aSpec, nsnull); +} + +nsresult +nsJARURI::SetSpecWithBase(const nsACString &aSpec, nsIURI* aBaseURL) { nsresult rv; + nsCOMPtr ioServ(do_GetIOService(&rv)); - if (NS_FAILED(rv)) return rv; + NS_ENSURE_SUCCESS(rv, rv); nsCAutoString scheme; rv = ioServ->ExtractScheme(aSpec, scheme); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) { + // not an absolute URI + if (!aBaseURL) + return NS_ERROR_MALFORMED_URI; - if (strcmp("jar", scheme.get()) != 0) - return NS_ERROR_MALFORMED_URI; + nsRefPtr otherJAR; + aBaseURL->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR)); + NS_ENSURE_TRUE(otherJAR, NS_NOINTERFACE); + + mJARFile = otherJAR->mJARFile; + + nsCOMPtr entry(do_CreateInstance(NS_STANDARDURL_CONTRACTID)); + if (!entry) + return NS_ERROR_OUT_OF_MEMORY; + + rv = entry->Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, + aSpec, mCharsetHint.get(), otherJAR->mJAREntry); + if (NS_FAILED(rv)) + return rv; + + mJAREntry = do_QueryInterface(entry); + if (!mJAREntry) + return NS_NOINTERFACE; + + return NS_OK; + } + + NS_ENSURE_TRUE(scheme.EqualsLiteral("jar"), NS_ERROR_MALFORMED_URI); + + nsACString::const_iterator begin, end; + aSpec.BeginReading(begin); + aSpec.EndReading(end); + + while (begin != end && *begin != ':') + ++begin; + + ++begin; // now we're past the "jar:" // Search backward from the end for the "!/" delimiter. Remember, jar URLs // can nest, e.g.: // jar:jar:http://www.foo.com/bar.jar!/a.jar!/b.html // This gets the b.html document from out of the a.jar file, that's // contained within the bar.jar file. + // Also, the outermost "inner" URI may be a relative URI: + // jar:../relative.jar!/a.html - nsACString::const_iterator begin, end, delim_begin, delim_end; - aSpec.BeginReading(begin); - aSpec.EndReading(end); - - delim_begin = begin; - delim_end = end; + nsACString::const_iterator delim_begin (begin), + delim_end (end); if (!RFindInReadable(NS_JAR_DELIMITER, delim_begin, delim_end)) return NS_ERROR_MALFORMED_URI; - begin.advance(4); - - rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(), nsnull, getter_AddRefs(mJARFile)); + rv = ioServ->NewURI(Substring(begin, delim_begin), mCharsetHint.get(), + aBaseURL, getter_AddRefs(mJARFile)); if (NS_FAILED(rv)) return rv; // skip over any extra '/' chars @@ -419,14 +454,16 @@ nsJARURI::GetOriginCharset(nsACString &aOriginCharset) NS_IMETHODIMP nsJARURI::Equals(nsIURI *other, PRBool *result) { + nsresult rv; + *result = PR_FALSE; if (other == nsnull) return NS_OK; // not equal nsRefPtr otherJAR; - nsresult rv = other->QueryInterface(kThisImplCID, getter_AddRefs(otherJAR)); - if (NS_FAILED(rv)) + other->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR)); + if (!otherJAR) return NS_OK; // not equal PRBool equal; diff --git a/mozilla/modules/libjar/nsJARURI.h b/mozilla/modules/libjar/nsJARURI.h index e16698b199f..ccd20e7aa75 100644 --- a/mozilla/modules/libjar/nsJARURI.h +++ b/mozilla/modules/libjar/nsJARURI.h @@ -74,6 +74,8 @@ public: NS_DECL_NSISERIALIZABLE NS_DECL_NSICLASSINFO + NS_DEFINE_STATIC_IID_ACCESSOR(NS_THIS_JARURI_IMPL_CID); + // nsJARURI nsJARURI(); virtual ~nsJARURI(); @@ -84,6 +86,7 @@ public: nsresult CreateEntryURL(const nsACString& entryFilename, const char* charset, nsIURL** url); + nsresult SetSpecWithBase(const nsACString& aSpec, nsIURI* aBaseURL); protected: nsCOMPtr mJARFile;