nsFileChannel::nsFileChannel(nsIURI *uri) { // If we have a link file, we should resolve its target right away. // This is to protect against a same origin attack where the same link file // can point to different resources right after the first resource is loaded. nsCOMPtr<nsIFile> file; nsCOMPtr <nsIURI> targetURI; nsAutoCString fileTarget; nsCOMPtr<nsIFile> resolvedFile; bool symLink; nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri); if (fileURL && NS_SUCCEEDED(fileURL->GetFile(getter_AddRefs(file))) && NS_SUCCEEDED(file->IsSymlink(&symLink)) && symLink && NS_SUCCEEDED(file->GetNativeTarget(fileTarget)) && NS_SUCCEEDED(NS_NewNativeLocalFile(fileTarget, PR_TRUE, getter_AddRefs(resolvedFile))) && NS_SUCCEEDED(NS_NewFileURI(getter_AddRefs(targetURI), resolvedFile, nullptr))) { SetURI(targetURI); SetOriginalURI(uri); nsLoadFlags loadFlags = 0; GetLoadFlags(&loadFlags); SetLoadFlags(loadFlags | nsIChannel::LOAD_REPLACE); } else { SetURI(uri); } }
NS_IMETHODIMP nsJARChannel::OnDownloadComplete(nsIDownloader *downloader, nsIRequest *request, nsISupports *context, nsresult status, nsIFile *file) { nsresult rv; nsCOMPtr<nsIChannel> channel(do_QueryInterface(request)); if (channel) { PRUint32 loadFlags; channel->GetLoadFlags(&loadFlags); if (loadFlags & LOAD_REPLACE) { mLoadFlags |= LOAD_REPLACE; if (!mOriginalURI) { SetOriginalURI(mJarURI); } nsCOMPtr<nsIURI> innerURI; rv = channel->GetURI(getter_AddRefs(innerURI)); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIJARURI> newURI; rv = mJarURI->CloneWithJARFile(innerURI, getter_AddRefs(newURI)); if (NS_SUCCEEDED(rv)) { mJarURI = newURI; } } if (NS_SUCCEEDED(status)) { status = rv; } } } if (NS_SUCCEEDED(status) && channel) { // Grab the security info from our base channel channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo)); nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); if (httpChannel) { // We only want to run scripts if the server really intended to // send us a JAR file. Check the server-supplied content type for // a JAR type. nsCAutoString header; httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"), header); nsCAutoString contentType; nsCAutoString charset; NS_ParseContentType(header, contentType, charset); nsCAutoString channelContentType; channel->GetContentType(channelContentType); mIsUnsafe = !(contentType.Equals(channelContentType) && (contentType.EqualsLiteral("application/java-archive") || contentType.EqualsLiteral("application/x-jar"))); } else { nsCOMPtr<nsIJARChannel> innerJARChannel(do_QueryInterface(channel)); if (innerJARChannel) { PRBool unsafe; innerJARChannel->GetIsUnsafe(&unsafe); mIsUnsafe = unsafe; } } channel->GetContentDisposition(mContentDisposition); } if (NS_SUCCEEDED(status) && mIsUnsafe) { PRBool allowUnpack = PR_FALSE; nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (prefs) { prefs->GetBoolPref("network.jar.open-unsafe-types", &allowUnpack); } if (!allowUnpack) { status = NS_ERROR_UNSAFE_CONTENT_TYPE; } } if (NS_SUCCEEDED(status)) { // Refuse to unpack view-source: jars even if open-unsafe-types is set. nsCOMPtr<nsIViewSourceChannel> viewSource = do_QueryInterface(channel); if (viewSource) { status = NS_ERROR_UNSAFE_CONTENT_TYPE; } } if (NS_SUCCEEDED(status)) { mJarFile = file; rv = CreateJarInput(nsnull); if (NS_SUCCEEDED(rv)) { // create input stream pump rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mJarInput); if (NS_SUCCEEDED(rv)) rv = mPump->AsyncRead(this, nsnull); } status = rv; } if (NS_FAILED(status)) { mStatus = status; OnStartRequest(nsnull, nsnull); OnStopRequest(nsnull, nsnull, status); } return NS_OK; }