nsresult ResourceReader::OnWalkURI(const nsACString& aURISpec, nsContentPolicyType aContentPolicyType) { nsresult rv; nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), aURISpec, mParent->GetCharacterSet(), mCurrentBaseURI); NS_ENSURE_SUCCESS(rv, rv); return OnWalkURI(uri, aContentPolicyType); }
nsresult ResourceReader::OnWalkAttribute(Element* aElement, nsContentPolicyType aContentPolicyType, const char* aAttribute, const char* aNamespaceURI) { nsAutoCString uriSpec; ExtractAttribute(aElement, aAttribute, aNamespaceURI, uriSpec); if (uriSpec.IsEmpty()) { return NS_OK; } return OnWalkURI(uriSpec, aContentPolicyType); }
nsresult ResourceReader::OnWalkAttribute(nsIDOMNode* aNode, const char* aAttribute, const char* aNamespaceURI) { nsAutoCString uriSpec; nsresult rv = ExtractAttribute(aNode, aAttribute, aNamespaceURI, uriSpec); NS_ENSURE_SUCCESS(rv, rv); if (uriSpec.IsEmpty()) { return NS_OK; } return OnWalkURI(uriSpec); }
nsresult ResourceReader::OnWalkDOMNode(nsINode* aNode) { // Fixup xml-stylesheet processing instructions if (auto nodeAsPI = dom::ProcessingInstruction::FromNode(aNode)) { nsAutoString target; nodeAsPI->GetTarget(target); if (target.EqualsLiteral("xml-stylesheet")) { nsAutoString href; GetXMLStyleSheetLink(nodeAsPI, href); if (!href.IsEmpty()) { return OnWalkURI(NS_ConvertUTF16toUTF8(href), nsIContentPolicy::TYPE_STYLESHEET); } } return NS_OK; } // Test the node to see if it's an image, frame, iframe, css, js if (aNode->IsHTMLElement(nsGkAtoms::img)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "src"); } if (aNode->IsSVGElement(nsGkAtoms::img)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "href", "http://www.w3.org/1999/xlink"); } if (aNode->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_MEDIA, "src"); } if (aNode->IsHTMLElement(nsGkAtoms::source)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_MEDIA, "src"); } if (aNode->IsHTMLElement(nsGkAtoms::body)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background"); } if (aNode->IsHTMLElement(nsGkAtoms::table)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background"); } if (aNode->IsHTMLElement(nsGkAtoms::tr)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background"); } if (aNode->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background"); } if (aNode->IsHTMLElement(nsGkAtoms::script)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_SCRIPT, "src"); } if (aNode->IsSVGElement(nsGkAtoms::script)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_SCRIPT, "href", "http://www.w3.org/1999/xlink"); } if (aNode->IsHTMLElement(nsGkAtoms::embed)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_OBJECT, "src"); } if (aNode->IsHTMLElement(nsGkAtoms::object)) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_OBJECT, "data"); } if (auto nodeAsLink = dom::HTMLLinkElement::FromNode(aNode)) { // Test if the link has a rel value indicating it to be a stylesheet nsAutoString linkRel; nodeAsLink->GetRel(linkRel); if (!linkRel.IsEmpty()) { nsReadingIterator<char16_t> start; nsReadingIterator<char16_t> end; nsReadingIterator<char16_t> current; linkRel.BeginReading(start); linkRel.EndReading(end); // Walk through space delimited string looking for "stylesheet" for (current = start; current != end; ++current) { // Ignore whitespace if (nsCRT::IsAsciiSpace(*current)) { continue; } // Grab the next space delimited word nsReadingIterator<char16_t> startWord = current; do { ++current; } while (current != end && !nsCRT::IsAsciiSpace(*current)); // Store the link for fix up if it says "stylesheet" if (Substring(startWord, current) .LowerCaseEqualsLiteral("stylesheet")) { OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_STYLESHEET, "href"); return NS_OK; } if (current == end) { break; } } } return NS_OK; } if (aNode->IsHTMLElement(nsGkAtoms::frame)) { return OnWalkSubframe(aNode); } if (aNode->IsHTMLElement(nsGkAtoms::iframe) && !(mPersistFlags & IWBP::PERSIST_FLAGS_IGNORE_IFRAMES)) { return OnWalkSubframe(aNode); } auto nodeAsInput = dom::HTMLInputElement::FromNode(aNode); if (nodeAsInput) { return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "src"); } return NS_OK; }
nsresult ResourceReader::OnWalkDOMNode(nsIDOMNode* aNode) { nsresult rv; // Fixup xml-stylesheet processing instructions nsCOMPtr<nsIDOMProcessingInstruction> nodeAsPI = do_QueryInterface(aNode); if (nodeAsPI) { nsAutoString target; rv = nodeAsPI->GetTarget(target); NS_ENSURE_SUCCESS(rv, rv); if (target.EqualsLiteral("xml-stylesheet")) { nsAutoString href; GetXMLStyleSheetLink(nodeAsPI, href); if (!href.IsEmpty()) { return OnWalkURI(NS_ConvertUTF16toUTF8(href)); } } return NS_OK; } nsCOMPtr<nsIContent> content = do_QueryInterface(aNode); if (!content) { return NS_OK; } // Test the node to see if it's an image, frame, iframe, css, js nsCOMPtr<nsIDOMHTMLImageElement> nodeAsImage = do_QueryInterface(aNode); if (nodeAsImage) { return OnWalkAttribute(aNode, "src"); } if (content->IsSVGElement(nsGkAtoms::img)) { return OnWalkAttribute(aNode, "href", "http://www.w3.org/1999/xlink"); } nsCOMPtr<nsIDOMHTMLMediaElement> nodeAsMedia = do_QueryInterface(aNode); if (nodeAsMedia) { return OnWalkAttribute(aNode, "src"); } nsCOMPtr<nsIDOMHTMLSourceElement> nodeAsSource = do_QueryInterface(aNode); if (nodeAsSource) { return OnWalkAttribute(aNode, "src"); } if (content->IsHTMLElement(nsGkAtoms::body)) { return OnWalkAttribute(aNode, "background"); } if (content->IsHTMLElement(nsGkAtoms::table)) { return OnWalkAttribute(aNode, "background"); } if (content->IsHTMLElement(nsGkAtoms::tr)) { return OnWalkAttribute(aNode, "background"); } if (content->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th)) { return OnWalkAttribute(aNode, "background"); } nsCOMPtr<nsIDOMHTMLScriptElement> nodeAsScript = do_QueryInterface(aNode); if (nodeAsScript) { return OnWalkAttribute(aNode, "src"); } if (content->IsSVGElement(nsGkAtoms::script)) { return OnWalkAttribute(aNode, "href", "http://www.w3.org/1999/xlink"); } nsCOMPtr<nsIDOMHTMLEmbedElement> nodeAsEmbed = do_QueryInterface(aNode); if (nodeAsEmbed) { return OnWalkAttribute(aNode, "src"); } nsCOMPtr<nsIDOMHTMLObjectElement> nodeAsObject = do_QueryInterface(aNode); if (nodeAsObject) { return OnWalkAttribute(aNode, "data"); } nsCOMPtr<nsIDOMHTMLAppletElement> nodeAsApplet = do_QueryInterface(aNode); if (nodeAsApplet) { // For an applet, relative URIs are resolved relative to the // codebase (which is resolved relative to the base URI). nsCOMPtr<nsIURI> oldBase = mCurrentBaseURI; nsAutoString codebase; rv = nodeAsApplet->GetCodeBase(codebase); NS_ENSURE_SUCCESS(rv, rv); if (!codebase.IsEmpty()) { nsCOMPtr<nsIURI> baseURI; rv = NS_NewURI(getter_AddRefs(baseURI), codebase, mParent->GetCharacterSet().get(), mCurrentBaseURI); NS_ENSURE_SUCCESS(rv, rv); if (baseURI) { mCurrentBaseURI = baseURI; // Must restore this before returning (or ENSURE'ing). } } // We only store 'code' locally if there is no 'archive', // otherwise we assume the archive file(s) contains it (bug 430283). nsAutoCString archiveAttr; rv = ExtractAttribute(aNode, "archive", "", archiveAttr); if (NS_SUCCEEDED(rv)) { if (!archiveAttr.IsEmpty()) { rv = OnWalkURI(archiveAttr); } else { rv = OnWalkAttribute(aNode, "core"); } } // restore the base URI we really want to have mCurrentBaseURI = oldBase; return rv; } nsCOMPtr<nsIDOMHTMLLinkElement> nodeAsLink = do_QueryInterface(aNode); if (nodeAsLink) { // Test if the link has a rel value indicating it to be a stylesheet nsAutoString linkRel; if (NS_SUCCEEDED(nodeAsLink->GetRel(linkRel)) && !linkRel.IsEmpty()) { nsReadingIterator<char16_t> start; nsReadingIterator<char16_t> end; nsReadingIterator<char16_t> current; linkRel.BeginReading(start); linkRel.EndReading(end); // Walk through space delimited string looking for "stylesheet" for (current = start; current != end; ++current) { // Ignore whitespace if (nsCRT::IsAsciiSpace(*current)) { continue; } // Grab the next space delimited word nsReadingIterator<char16_t> startWord = current; do { ++current; } while (current != end && !nsCRT::IsAsciiSpace(*current)); // Store the link for fix up if it says "stylesheet" if (Substring(startWord, current) .LowerCaseEqualsLiteral("stylesheet")) { OnWalkAttribute(aNode, "href"); return NS_OK; } if (current == end) { break; } } } return NS_OK; } nsCOMPtr<nsIDOMHTMLFrameElement> nodeAsFrame = do_QueryInterface(aNode); if (nodeAsFrame) { return OnWalkSubframe(aNode); } nsCOMPtr<nsIDOMHTMLIFrameElement> nodeAsIFrame = do_QueryInterface(aNode); if (nodeAsIFrame && !(mPersistFlags & IWBP::PERSIST_FLAGS_IGNORE_IFRAMES)) { return OnWalkSubframe(aNode); } nsCOMPtr<nsIDOMHTMLInputElement> nodeAsInput = do_QueryInterface(aNode); if (nodeAsInput) { return OnWalkAttribute(aNode, "src"); } return NS_OK; }