/** * Creates a new print writer which performs the tag injection. * * @param originalWriter * The writer which is wrapped. * @param tagToInject * The tag(s) to insert. */ public TagInjectionPrintWriter(PrintWriter originalWriter, String tagToInject) { super(originalWriter); this.originalWriter = originalWriter; injector = new StreamedHtmlScriptInjector(tagToInject); }
@Override public PrintWriter append(CharSequence csq) { String newValue = injector.performInjection(csq); if (newValue == null) { originalWriter.append(csq); } else { originalWriter.write(newValue); } return this; }
/** * {@inheritDoc} */ @Override protected void abortInjectionPointSearch() { super.abortInjectionPointSearch(); leftOver = NO_LEFTOVER_CHARACTER_BYTES; encodeBuffer = null; // NOPMD decodeBuffer = null; // NOPMD }
scanXmlDeclaration(); break; case SCAN_REQUIRED_XHTML_PREAMBLE: scanRequiredXHtmlPreamble(); break; case SCAN_HTML_PREAMBLE: scanHtmlPreamble(); break; case SCAN_FOR_HTML_TAG: scanForHtmlTag(); break; case SCAN_FOR_HEAD_TAG: scanForHeadTag(); break; case SCAN_FOR_BODY_TAG: scanForBodyTag(); break; default:
@Test public void testPreventDoubleInejection() { String src = loadHtmlSource("/html/testCase-HeadInjection.html"); String modifiedA = runInjector(src); String modified = new StreamedHtmlScriptInjector(TAG_TO_INJECT).performInjection(modifiedA); assertThat(modified, equalTo(null)); }
/** * Tries to find an opening html tag. */ private void scanForHtmlTag() { if (CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagType(), "html")) { if (tokenParser.getParsedTokenType() != Token.START_TAG) { abortInjectionPointSearch(); return; } status = Status.SCAN_FOR_HEAD_TAG; } else { // current token is not the html tag, we assume the document starts immediately with the // head status = Status.SCAN_FOR_HEAD_TAG; processToken(); } }
if (hasTerminated()) { return null; while (!hasTerminated()) { Result tokenParsingResult = tokenParser.parseToken(); switch (tokenParsingResult) { case FAILURE: abortInjectionPointSearch(); return null; case INCOMPLETE: return null; case SUCCESS: processToken(); if (status == Status.INJECTION_POINT_FOUND) { String returnValue; abortInjectionPointSearch(); return returnValue; } else if (status != Status.TERMINATED) {
/** * Tries to find an opening head tag. Omitting both the head and the body tag is currently not * supported. */ private void scanForHeadTag() { if (CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagType(), "head")) { if (tokenParser.getParsedTokenType() != Token.START_TAG) { abortInjectionPointSearch(); return; } // Perform injection after start of the head tag status = Status.INJECTION_POINT_FOUND; } else { // current token is not the head tag, we assume it must be the body tag (head is empty) status = Status.SCAN_FOR_BODY_TAG; processToken(); } }
@Override public void println(float x) { String newValue = injector.performInjection(x + NL); if (newValue == null) { originalWriter.println(x); } else { originalWriter.write(newValue); } }
/** * Scans for an opening <?xml .. ?> declaration in case the html is delivered as XML. */ private void scanXmlDeclaration() { // Preamble checking based on the information on this page if (CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagType(), "?xml")) { // ?> is treated by the parser as a stand-alone tag if (tokenParser.getParsedTokenType() != Token.STANDALONE_TAG) { abortInjectionPointSearch(); return; } // Xml header detected, now we require an html doctype to continue status = Status.SCAN_REQUIRED_XHTML_PREAMBLE; } else { // no xml tag found, therefore we are non-strict in requiring a doctype declaration status = Status.SCAN_HTML_PREAMBLE; processToken(); } }
@BeforeMethod public void init() { injector = new StreamedHtmlScriptInjector(TAG_TO_INJECT); }
/** * Tries to find an opening body tag. Omitting both the head and the body tag is currently not * supported. */ private void scanForBodyTag() { if (CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagType(), "body")) { if (tokenParser.getParsedTokenType() != Token.START_TAG) { abortInjectionPointSearch(); return; } // Perform injection after start of the head tag status = Status.INJECTION_POINT_FOUND; } else { // current token is not the head tag, we assume it must be the body tag (head is empty) abortInjectionPointSearch(); } }
@Override public void println(double x) { String newValue = injector.performInjection(x + NL); if (newValue == null) { originalWriter.println(x); } else { originalWriter.write(newValue); } }
/** * Scans for an opening html tag, skipping preamble tags like or !DOCTYPE. */ private void scanHtmlPreamble() { // Preamble checking based on the information on this page // http://wiki.selfhtml.org/wiki/HTML/Dokumentstruktur_und_Aufbau#HTML5 // we also allow html without preamble, directly starting with the <html> tag if (CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagType(), "!DOCTYPE")) { // Doctypes are formated as opening tags if (tokenParser.getParsedTokenType() != Token.START_TAG) { abortInjectionPointSearch(); return; } // we accept any doctype starting with "html" if (!CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagArguments(), 0, 4, "html", 0, 4)) { abortInjectionPointSearch(); return; } // DOCTYPE okay, proceed with the next tag scanning for the html tag status = Status.SCAN_FOR_HTML_TAG; } else { // no preamble tag found, we assume the html is starting immediately status = Status.SCAN_FOR_HTML_TAG; processToken(); } }
/** * Same as {@link #scanHtmlPreamble()}, however does not allow to ommit the preamble. */ private void scanRequiredXHtmlPreamble() { // Preamble checking based on the information on this page // http://wiki.selfhtml.org/wiki/HTML/Dokumentstruktur_und_Aufbau#HTML5 // we also allow html without preamble, directly starting with the <html> tag if (CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagType(), "!DOCTYPE")) { // Doctypes are formated as opening tags if (tokenParser.getParsedTokenType() != Token.START_TAG) { abortInjectionPointSearch(); return; } // we accept any doctype starting with "html" if (!CharSequenceUtils.checkEqualIgnoreCase(tokenParser.getTagArguments(), 0, 4, "html", 0, 4)) { abortInjectionPointSearch(); return; } // DOCTYPE okay, proceed with the next tag scanning for the html tag status = Status.SCAN_FOR_HTML_TAG; } else { // no preamble tag found, it however is required for xhtml abortInjectionPointSearch(); return; } }
@Override public void println(Object x) { String newValue = injector.performInjection(x + NL); if (newValue == null) { originalWriter.println(x); } else { originalWriter.write(newValue); } }
@Override public void write(String s) { String newValue = injector.performInjection(s); if (newValue == null) { originalWriter.write(s); } else { originalWriter.write(newValue); } }
@Override public void println(String x) { String newValue = injector.performInjection(x + NL); if (newValue == null) { originalWriter.println(x); } else { originalWriter.write(newValue); } }
@Override public void println() { String newValue = injector.performInjection(NL); if (newValue == null) { originalWriter.println(); } else { originalWriter.write(newValue); } }
@Override public void println(long x) { String newValue = injector.performInjection(x + NL); if (newValue == null) { originalWriter.println(x); } else { originalWriter.write(newValue); } }