Skip to content

Commit

Permalink
Reorg to add other safehtml bits. JRE tests pass, gwt not yet
Browse files Browse the repository at this point in the history
  • Loading branch information
niloc132 committed Dec 11, 2017
1 parent 78afd06 commit 6896cc6
Show file tree
Hide file tree
Showing 51 changed files with 3,663 additions and 45 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
target/
.project
.classpath
.settings/
*.iml
atlassian-ide-plugin.xml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
package com.google.gwt.safehtml.apt;
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.gwtproject.safehtml.apt;

import com.google.common.base.Preconditions;
import com.google.gwt.safehtml.apt.ParsedHtmlTemplate.HtmlContext;
import com.google.gwt.safehtml.apt.ParsedHtmlTemplate.ParameterChunk;
import com.google.gwt.thirdparty.streamhtmlparser.HtmlParser;
import com.google.gwt.thirdparty.streamhtmlparser.HtmlParserFactory;
import com.google.gwt.thirdparty.streamhtmlparser.ParseException;
Expand Down Expand Up @@ -185,7 +198,7 @@ void parseTemplate(String template) throws UnableToCompleteException {
lookAhead = 0;
}
parsedTemplate.addParameter(
new ParameterChunk(getHtmlContextFromParseState(), paramIndex));
new ParsedHtmlTemplate.ParameterChunk(getHtmlContextFromParseState(), paramIndex));

endOfPreviousMatch = match.end();
}
Expand Down Expand Up @@ -218,7 +231,7 @@ void parseTemplate(String template) throws UnableToCompleteException {
* @throws UnableToCompleteException if an illegal/unuspported template
* construct is encountered
*/
private HtmlContext getHtmlContextFromParseState()
private ParsedHtmlTemplate.HtmlContext getHtmlContextFromParseState()
throws UnableToCompleteException {
// TODO(xtof): Consider refactoring such that state related to the position
// of the template variable in an attribute is exposed separately (as
Expand All @@ -245,7 +258,7 @@ private HtmlContext getHtmlContextFromParseState()
throw new UnableToCompleteException();
} else if (streamHtmlParser.getState().equals(HtmlParser.STATE_TEXT)
&& !streamHtmlParser.inCss()) {
return new HtmlContext(HtmlContext.Type.TEXT);
return new ParsedHtmlTemplate.HtmlContext(ParsedHtmlTemplate.HtmlContext.Type.TEXT);
} else if (streamHtmlParser.getState().equals(HtmlParser.STATE_VALUE)) {
final String tag = streamHtmlParser.getTag();
final String attribute = streamHtmlParser.getAttribute();
Expand Down Expand Up @@ -280,22 +293,22 @@ private HtmlContext getHtmlContextFromParseState()
// a quote that matches the one that started the attribute, we know
// that the parameter comprises the entire attribute.
if (lookAhead == lookBehind) {
return new HtmlContext(HtmlContext.Type.URL_ATTRIBUTE_ENTIRE, tag, attribute);
return new ParsedHtmlTemplate.HtmlContext(ParsedHtmlTemplate.HtmlContext.Type.URL_ATTRIBUTE_ENTIRE, tag, attribute);
} else {
return new HtmlContext(HtmlContext.Type.URL_ATTRIBUTE_START, tag, attribute);
return new ParsedHtmlTemplate.HtmlContext(ParsedHtmlTemplate.HtmlContext.Type.URL_ATTRIBUTE_START, tag, attribute);
}
} else if (streamHtmlParser.inCss()) {
if (streamHtmlParser.getValueIndex() == 0) {
return new HtmlContext(HtmlContext.Type.CSS_ATTRIBUTE_START, tag, attribute);
return new ParsedHtmlTemplate.HtmlContext(ParsedHtmlTemplate.HtmlContext.Type.CSS_ATTRIBUTE_START, tag, attribute);
} else {
return new HtmlContext(HtmlContext.Type.CSS_ATTRIBUTE, tag, attribute);
return new ParsedHtmlTemplate.HtmlContext(ParsedHtmlTemplate.HtmlContext.Type.CSS_ATTRIBUTE, tag, attribute);
}
} else {
return new HtmlContext(
HtmlContext.Type.ATTRIBUTE_VALUE, tag, attribute);
return new ParsedHtmlTemplate.HtmlContext(
ParsedHtmlTemplate.HtmlContext.Type.ATTRIBUTE_VALUE, tag, attribute);
}
} else if (streamHtmlParser.inCss()) {
return new HtmlContext(HtmlContext.Type.CSS);
return new ParsedHtmlTemplate.HtmlContext(ParsedHtmlTemplate.HtmlContext.Type.CSS);
} else if (streamHtmlParser.getState().equals(HtmlParser.STATE_TAG)
|| streamHtmlParser.inAttribute()) {
LOGGER.log(Level.SEVERE,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
package com.google.gwt.safehtml.apt;
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.gwtproject.safehtml.apt;

import com.google.common.base.Preconditions;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.google.gwt.safehtml.apt;
package org.gwtproject.safehtml.apt;

import com.google.gwt.codegen.server.AbortablePrintWriter;
import com.google.gwt.codegen.server.JavaSourceWriterBuilder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package com.google.gwt.safehtml.apt;
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.gwtproject.safehtml.apt;

import com.google.common.primitives.Primitives;
import com.google.gwt.codegen.server.SourceWriter;
import com.google.gwt.safecss.shared.SafeStyles;
import com.google.gwt.safehtml.apt.ParsedHtmlTemplate.HtmlContext;
import com.google.gwt.safehtml.apt.ParsedHtmlTemplate.LiteralChunk;
import com.google.gwt.safehtml.apt.ParsedHtmlTemplate.ParameterChunk;
import com.google.gwt.safehtml.apt.ParsedHtmlTemplate.TemplateChunk;
import com.google.gwt.safehtml.client.SafeHtmlTemplates.Template;
import com.google.gwt.safehtml.shared.OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml;
import com.google.gwt.safehtml.shared.SafeHtml;
Expand Down Expand Up @@ -128,7 +139,7 @@ public void createMethodFor(Template templateAnnotation, String[] params) throws
* @param parameterType the Java type of the corresponding template method's
* parameter
*/
private void emitAttributeContextParameterExpression(HtmlContext htmlContext,
private void emitAttributeContextParameterExpression(ParsedHtmlTemplate.HtmlContext htmlContext,
String formalParameterName, String parameterType) {

/*
Expand All @@ -149,8 +160,8 @@ private void emitAttributeContextParameterExpression(HtmlContext htmlContext,
expression = "String.valueOf(" + expression + ")";
}

if ((htmlContext.getType() == HtmlContext.Type.URL_ATTRIBUTE_START) ||
(htmlContext.getType() == HtmlContext.Type.URL_ATTRIBUTE_ENTIRE)) {
if ((htmlContext.getType() == ParsedHtmlTemplate.HtmlContext.Type.URL_ATTRIBUTE_START) ||
(htmlContext.getType() == ParsedHtmlTemplate.HtmlContext.Type.URL_ATTRIBUTE_ENTIRE)) {
expression = URI_UTILS_FQCN + ".sanitizeUri(" + expression + ")";
}
}
Expand Down Expand Up @@ -186,14 +197,14 @@ private void emitMethodBodyFromTemplate(String template, String[] params)
throws UnableToCompleteException {
println("StringBuilder sb = new java.lang.StringBuilder();");

com.google.gwt.safehtml.apt.HtmlTemplateParser parser = new com.google.gwt.safehtml.apt.HtmlTemplateParser();
HtmlTemplateParser parser = new HtmlTemplateParser();
parser.parseTemplate(template);

for (TemplateChunk chunk : parser.getParsedTemplate().getChunks()) {
if (chunk.getKind() == TemplateChunk.Kind.LITERAL) {
emitStringLiteral(((LiteralChunk) chunk).getLiteral());
} else if (chunk.getKind() == TemplateChunk.Kind.PARAMETER) {
ParameterChunk parameterChunk = (ParameterChunk) chunk;
for (ParsedHtmlTemplate.TemplateChunk chunk : parser.getParsedTemplate().getChunks()) {
if (chunk.getKind() == ParsedHtmlTemplate.TemplateChunk.Kind.LITERAL) {
emitStringLiteral(((ParsedHtmlTemplate.LiteralChunk) chunk).getLiteral());
} else if (chunk.getKind() == ParsedHtmlTemplate.TemplateChunk.Kind.PARAMETER) {
ParsedHtmlTemplate.ParameterChunk parameterChunk = (ParsedHtmlTemplate.ParameterChunk) chunk;

int formalParameterIndex = parameterChunk.getParameterIndex();
if (formalParameterIndex < 0 || formalParameterIndex >= params.length) {
Expand Down Expand Up @@ -230,24 +241,24 @@ private void emitMethodBodyFromTemplate(String template, String[] params)
* @throws UnableToCompleteException if the parameterType is not valid for the
* htmlContext
*/
private void emitParameterExpression(HtmlContext htmlContext,
private void emitParameterExpression(ParsedHtmlTemplate.HtmlContext htmlContext,
String formalParameterName, String parameterType) throws UnableToCompleteException {

/*
* Verify that the parameter type is used in the correct context. Safe
* expressions are only safe in specific contexts.
*/
HtmlContext.Type contextType = htmlContext.getType();
if (isSafeHtml(parameterType) && HtmlContext.Type.TEXT != contextType) {
ParsedHtmlTemplate.HtmlContext.Type contextType = htmlContext.getType();
if (isSafeHtml(parameterType) && ParsedHtmlTemplate.HtmlContext.Type.TEXT != contextType) {
/*
* SafeHtml used in a non-text context. SafeHtml is escaped for a text
* context. In a non-text context, the string is not guaranteed to be
* safe.
*/
throw error(SAFE_HTML_CN + " used in a non-text context. Did you mean to use "
+ JAVA_LANG_STRING_FQCN + " or " + SAFE_STYLES_CN + " instead?");
} else if (isSafeStyles(parameterType) && HtmlContext.Type.CSS_ATTRIBUTE_START != contextType) {
if (HtmlContext.Type.CSS_ATTRIBUTE == contextType) {
} else if (isSafeStyles(parameterType) && ParsedHtmlTemplate.HtmlContext.Type.CSS_ATTRIBUTE_START != contextType) {
if (ParsedHtmlTemplate.HtmlContext.Type.CSS_ATTRIBUTE == contextType) {
// SafeStyles can only be used at the start of a CSS attribute.
throw error(SAFE_STYLES_CN + " cannot be used in the middle of a CSS attribute. "
+ "It must be used at the start a CSS attribute.");
Expand All @@ -262,9 +273,9 @@ private void emitParameterExpression(HtmlContext htmlContext,
+ " used in a non-CSS attribute context. Did you mean to use " + JAVA_LANG_STRING_FQCN
+ " or " + SAFE_HTML_CN + " instead?");
}
} else if (isSafeUri(parameterType) && HtmlContext.Type.URL_ATTRIBUTE_ENTIRE != contextType) {
} else if (isSafeUri(parameterType) && ParsedHtmlTemplate.HtmlContext.Type.URL_ATTRIBUTE_ENTIRE != contextType) {
// TODO(xtof): refactor HtmlContext with isStart/isEnd/isEntire accessors and simplified type.
if (HtmlContext.Type.URL_ATTRIBUTE_START == contextType) {
if (ParsedHtmlTemplate.HtmlContext.Type.URL_ATTRIBUTE_START == contextType) {
// SafeUri can only be used as the entire value of an URL attribute.
throw error(SAFE_URI_CN + " cannot be used in a URL attribute if it isn't the "
+ "entire attribute value.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.gwtproject.safehtml.apt;

/**
* TODO kill this class
*/
public class UnableToCompleteException extends Exception {
}
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
com.google.gwt.safehtml.apt.SafeHtmlProcessor
com.programmaticallyspeaking.aptdemo.AnnotationProcessor
org.gwtproject.safehtml.apt.SafeHtmlProcessor
23 changes: 22 additions & 1 deletion shared/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,36 @@


<dependencies>
<dependency>
<groupId>com.google.elemental2</groupId>
<artifactId>elemental2-core</artifactId>
<version>1.0.0-beta-3</version>
</dependency>


<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>2.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>

<build>

<testResources>
<testResource>
<directory>src/test/java</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package org.gwtproject.safehtml.client;

import org.gwtproject.safehtml.shared.SafeHtml;

/**
* An object that implements this interface contains text with HTML markup,
* which can be set with the Cross-Site-Scripting-safe HTML markup encapsulated
* in a {@link org.gwtproject.safehtml.shared.SafeHtml} object.
*/
public interface HasSafeHtml {

/**
* Sets this object's contents via known-safe HTML.
*
* <p>
* The object will behave exactly the same as when a widget's
* {@code com.google.gwt.user.client.ui.HasHTML#setHTML(String)} method is
* invoked; however the {@link SafeHtml} passed to this method observes the
* contract that it can be used in an HTML context without causing unsafe
* script execution. Thus, unlike
* {@code com.google.gwt.user.client.ui.HasHTML#setHTML(String)}, using this
* method cannot result in Cross-Site Scripting security vulnerabilities.
*
* @param html the object's new HTML, represented as a {@link SafeHtml} object
*/
void setHTML(SafeHtml html);
}
Loading

0 comments on commit 6896cc6

Please sign in to comment.