Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #865 from xael-fry/1937_routerImprovBr1.2.6.x
Browse files Browse the repository at this point in the history
[#1937] fix(router): make some improvement in router
  • Loading branch information
xael-fry committed Apr 28, 2015
2 parents ae1b263 + 67a2a77 commit ca0912f
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 56 deletions.
14 changes: 14 additions & 0 deletions .travis.yml
@@ -0,0 +1,14 @@
language: java
jdk:
- openjdk6
script: ant -buildfile ./framework/build.xml test
after_failure:
cat ./samples-and-tests/just-test-cases/test-result/*.failed.html
cat ./samples-and-tests/forum/test-result/*.failed.html
cat ./samples-and-tests/zencontact/test-result/*.failed.html
cat ./samples-and-tests/jobboard/test-result/*.failed.html
cat ./samples-and-tests/yabe/test-result/*.failed.html
notifications:
email:
on_success: change
on_failure: always
15 changes: 15 additions & 0 deletions framework/src/play/db/DBPlugin.java
Expand Up @@ -11,15 +11,19 @@
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import jregex.Matcher;

import org.apache.commons.lang.StringUtils;

import play.Logger;
import play.Play;
import play.PlayPlugin;
Expand Down Expand Up @@ -338,6 +342,17 @@ public DriverPropertyInfo[] getPropertyInfo(String u, Properties p) throws SQLEx
public boolean jdbcCompliant() {
return this.driver.jdbcCompliant();
}

// Method not annotated with @Override since getParentLogger() is a new method
// in the CommonDataSource interface starting with JDK7 and this annotation
// would cause compilation errors with JDK6.
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
try {
return (java.util.logging.Logger) Driver.class.getDeclaredMethod("getParentLogger").invoke(this.driver);
} catch (Throwable e) {
return null;
}
}
}

public static class PlayConnectionCustomizer implements ConnectionCustomizer {
Expand Down
52 changes: 39 additions & 13 deletions framework/src/play/libs/XML.java
@@ -1,9 +1,6 @@
package play.libs;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.*;
import java.security.Key;
import java.security.Provider;
import java.security.interfaces.RSAPrivateKey;
Expand All @@ -26,6 +23,7 @@
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
Expand All @@ -46,6 +44,25 @@
*/
public class XML {

public static DocumentBuilderFactory newDocumentBuilderFactory() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
return dbf;
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
}

public static DocumentBuilder newDocumentBuilder() {
try {
return newDocumentBuilderFactory().newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
}

/**
* Serialize to XML String
* @param document The DOM document
Expand All @@ -58,7 +75,7 @@ public static String serialize(Document document) {
Transformer transformer = factory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(writer);
transformer.transform(domSource, streamResult);
transformer.transform(domSource, streamResult);
} catch (TransformerException e) {
throw new RuntimeException(
"Error when serializing XML document.", e);
Expand All @@ -69,18 +86,15 @@ public static String serialize(Document document) {
/**
* Parse an XML file to DOM
* @return null if an error occurs during parsing.
*
*
*/
public static Document getDocument(File file) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
return dbf.newDocumentBuilder().parse(file);
return newDocumentBuilder().parse(file);
} catch (SAXException e) {
Logger.warn("Parsing error when building Document object from xml file '" + file + "'.", e);
} catch (IOException e) {
Logger.warn("Reading error when building Document object from xml file '" + file + "'.", e);
} catch (ParserConfigurationException e) {
Logger.warn("Parsing error when building Document object from xml file '" + file + "'.", e);
}
return null;
}
Expand All @@ -91,15 +105,27 @@ public static Document getDocument(File file) {
*/
public static Document getDocument(String xml) {
InputSource source = new InputSource(new StringReader(xml));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
return dbf.newDocumentBuilder().parse(source);
return newDocumentBuilder().parse(source);
} catch (SAXException e) {
Logger.warn("Parsing error when building Document object from xml data.", e);
} catch (IOException e) {
Logger.warn("Reading error when building Document object from xml data.", e);
} catch (ParserConfigurationException e) {
}
return null;
}

/**
* Parse an XML coming from an input stream to DOM
* @return null if an error occurs during parsing.
*/
public static Document getDocument(InputStream stream) {
try {
return newDocumentBuilder().parse(stream);
} catch (SAXException e) {
Logger.warn("Parsing error when building Document object from xml data.", e);
} catch (IOException e) {
Logger.warn("Reading error when building Document object from xml data.", e);
}
return null;
}
Expand Down
24 changes: 14 additions & 10 deletions framework/src/play/mvc/Router.java
Expand Up @@ -509,11 +509,13 @@ public static ActionDefinition reverse(String action, Map<String, Object> args)
try {
queryString.append(URLEncoder.encode(key, encoding));
queryString.append("=");
if (object.toString().startsWith(":")) {
queryString.append(object.toString());
} else {
queryString.append(URLEncoder.encode(object.toString() + "", encoding));
}
String objStr = object.toString();
// Special case to handle jsAction tag
if (objStr.startsWith(":") && objStr.length() > 1) {
queryString.append(':');
objStr = objStr.substring(1);
}
queryString.append(URLEncoder.encode(objStr + "", encoding));
queryString.append("&");
} catch (UnsupportedEncodingException ex) {
}
Expand All @@ -524,11 +526,13 @@ public static ActionDefinition reverse(String action, Map<String, Object> args)
try {
queryString.append(URLEncoder.encode(key, encoding));
queryString.append("=");
if (value.toString().startsWith(":")) {
queryString.append(value.toString());
} else {
queryString.append(URLEncoder.encode(value.toString() + "", encoding));
}
String objStr = value.toString();
// Special case to handle jsAction tag
if (objStr.startsWith(":") && objStr.length() > 1) {
queryString.append(':');
objStr = objStr.substring(1);
}
queryString.append(URLEncoder.encode(objStr + "", encoding));
queryString.append("&");
} catch (UnsupportedEncodingException ex) {
}
Expand Down
23 changes: 22 additions & 1 deletion framework/src/play/templates/FastTags.java
Expand Up @@ -59,7 +59,28 @@ public static void _verbatim(Map<?, ?> args, Closure body, PrintWriter out, Exec
}

public static void _jsAction(Map<?, ?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) {
out.println("function(options) {var pattern = '" + args.get("arg").toString().replace("&amp;", "&") + "'; for(var key in options) { pattern = pattern.replace(':'+key, options[key] || ''); } return pattern }");
String html = "";
String minimize = "";
if(args.containsKey("minimize") && Boolean.FALSE.equals(Boolean.valueOf(args.get("minimize").toString()))){
minimize = "\n";
}
html += "function(options) {" + minimize;
html += "var pattern = '" + args.get("arg").toString().replace("&amp;", "&") + "';" + minimize;;
html += "for(key in options) {" + minimize;;
html += "var val = options[key];" + minimize;
// Encode URI script
if(args.containsKey("encodeURI") && Boolean.TRUE.equals(Boolean.valueOf(args.get("encodeURI").toString()))){
html += "val = encodeURIComponent(val.replace('&amp;', '&'));" + minimize;
}
//Custom script
if(args.containsKey("customScript")){
html += "val = " + args.get("customScript") + minimize;
}
html += "pattern = pattern.replace(':' + encodeURIComponent(key), val || '');"+ minimize;
html += "}" + minimize;;
html += "return pattern;" + minimize;;
html += "}" + minimize;
out.println(html);
}

public static void _jsRoute(Map<?, ?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) {
Expand Down
84 changes: 52 additions & 32 deletions samples-and-tests/just-test-cases/app/controllers/Users.java
Expand Up @@ -38,39 +38,59 @@ public static void changeColors(List<Factory.Color> colors) {
}

public static void edit() {
User u = fresh();
render(u);
}

public static void save() {
User u = fresh();
u.edit(params.getRootParamNode(), "u");
render(u);
}

static User fresh() {
try {
User u = new User();
u.name = "Guillaume";
u.b = true;
u.l = 356L;
u.birth = new SimpleDateFormat("dd/MM/yyyy").parse("21/12/1980");
return u;
} catch(Exception e) {
throw new RuntimeException(e);
}
}

public static void wbyte(byte a, Byte b) {
renderText(a+","+b);
}

public static void newUser(String name) {
User u = new User();
u.name = name;
u.save();
renderText("Created user with name %s", u.name);
User u = fresh();
render(u);
}

public static void save() {
User u = fresh();
u.edit(params.getRootParamNode(), "u");
render(u);
}

static User fresh() {
try {
User u = new User();
u.name = "Guillaume";
u.b = true;
u.l = 356L;
u.birth = new SimpleDateFormat("dd/MM/yyyy").parse("21/12/1980");
return u;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static void wbyte(byte a, Byte b) {
renderText(a + "," + b);
}

public static void newUser(String name) {
User u = new User();
u.name = name;
u.save();
renderText("Created user with name %s", u.name);
}

public static void showAll() {
List<User> users = User.find("order by name ASC").fetch();
render(users);
}

public static void showId(Long id) {
User u = User.findById(id);
if (u != null) {
renderText(u.name);
}
renderText("");
}

public static void showName(String name) {
User u = User.find("byName", name).first();
if (u != null) {
renderText(u.name);
}
renderText("");
}
}

@@ -0,0 +1,16 @@
package controllers.security;

import play.mvc.Controller;



/**
* Test controller to check response to Xss attempt.
*/
public class XssAttempts extends Controller {

public static void testUrlParam(String url){
render(url);
}

}
54 changes: 54 additions & 0 deletions samples-and-tests/just-test-cases/app/views/Users/showAll.html
@@ -0,0 +1,54 @@
#{extends 'main.html' /}
<script src="@{'/public/jquery.js'}" type="text/javascript" charset="${_response_encoding}"></script>

<script type="text/javascript" charset="${_response_encoding}" >
var showUserAction = #{jsAction @Users.showId(':id')/}
// check accents in keys
var showUserNameAction = #{jsAction @Users.showName(':nâmë'), encodeURI:false, minimize:true /}
var showUserNameActionEncodeURI = #{jsAction @Users.showName(':name'), encodeURI:true, minimize:false /}
var showUserNameActionCustomScript= #{jsAction @Users.showName(':name'), customScript:"encodeURIComponent(val.replace('&amp;', '&'))", minimize:false /}

$(document).ready(function() {
var html = ""
var id = 1;

#{list items:users, as:'user'}
html ="<tr id=\"" + ${user_index} +"\">";
html += "<td>" + "${user.name}" + "</td>";
html += "<td></td>";
html += "<td></td>";
html += "<td></td>";
html += "<td></td>";
html += "</tr>";
$('#content tbody').append(html);

$('#' + ${user_index} + ' td').eq(1).load( showUserAction({id: "${user?.id}"}) );
$('#' + ${user_index} + ' td').eq(2).load( showUserNameAction({nâmë: "${user?.name?.urlEncode()}"}) );
$('#' + ${user_index} + ' td').eq(3).load( showUserNameActionEncodeURI({name: "${user?.name}" }) );
$('#' + ${user_index} + ' td').eq(4).load( showUserNameActionCustomScript({name: "${user?.name}" }) );
id = "${user?.id}";
#{/list}

// manual add
html ="<tr id=\"javascript_add\">";
html += "<td>" + "name with special characters [c c ; %20 , / ? : @ & = + $ #]" + "</td>";
html += "<td></td>";
html += "<td></td>";
html += "<td></td>";
html += "<td></td>";
html += "</tr>";
$('#content tbody').append(html);
$('#' + 'javascript_add' + ' td').eq(1).load( showUserAction({id: id}) );
$('#' + 'javascript_add' + ' td').eq(2).load( showUserNameAction({nâmë: encodeURIComponent("name with special characters [c c ; %20 , / ? : @ & = + $ #]") }) );
$('#' + 'javascript_add' + ' td').eq(3).load( showUserNameActionEncodeURI({name: "name with special characters [c c ; %20 , / ? : @ & = + $ #]" }) );
$('#' + 'javascript_add' + ' td').eq(4).load( showUserNameActionCustomScript({name: "name with special characters [c c ; %20 , / ? : @ & = + $ #]" }) );
});

</script>


<table id="content">
<thead><tr><th>Name</th><th>Name From ID</th> <th>UrlEncode</th><th>jsAction urlEncode</th><th>jsAction customScript</th></tr></thead>
<tbody></tbody>
</table>

0 comments on commit ca0912f

Please sign in to comment.