Author: mreutegg Date: Fri Feb 9 05:44:04 2007 New Revision: 505286 URL: http://svn.apache.org/viewvc?view=rev&rev=505286 Log: JCR-739: Predefined entity references are not decoded in string literal Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java?view=diff&rev=505286&r1=505285&r2=505286 ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java Fri Feb 9 05:44:04 2007 @@ -666,7 +666,8 @@ */ private void assignValue(SimpleNode node, RelationQueryNode queryNode) { if (node.getId() == JJTSTRINGLITERAL) { - queryNode.setStringValue(unescapeQuotes(node.getValue())); + queryNode.setStringValue(unescapeQuotes( + decodePredefinedEntities(node.getValue()))); } else if (node.getId() == JJTDECIMALLITERAL) { queryNode.setDoubleValue(Double.parseDouble(node.getValue())); } else if (node.getId() == JJTDOUBLELITERAL) { @@ -744,8 +745,10 @@ if (queryNode instanceof NAryQueryNode) { SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0); if (literal.getId() == JJTSTRINGLITERAL) { - TextsearchQueryNode contains = new TextsearchQueryNode(queryNode, - unescapeQuotes(literal.getValue())); + TextsearchQueryNode contains = new TextsearchQueryNode( + queryNode, + unescapeQuotes(decodePredefinedEntities( + literal.getValue()))); // assign property name SimpleNode path = (SimpleNode) node.jjtGetChild(1); path.jjtAccept(this, contains); @@ -774,7 +777,8 @@ SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0); if (literal.getId() == JJTSTRINGLITERAL) { - like.setStringValue(unescapeQuotes(literal.getValue())); + like.setStringValue(unescapeQuotes( + decodePredefinedEntities(literal.getValue()))); } else { exceptions.add(new InvalidQueryException("Wrong second argument type for jcr:like")); } @@ -856,6 +860,7 @@ String value = literal.getValue(); // strip quotes value = value.substring(1, value.length() - 1); + value = decodePredefinedEntities(value); if (!value.equals("*")) { QName name = null; try { @@ -1022,5 +1027,57 @@ value = value.replaceAll("''", "'"); } return value; + } + + /** + * Decodes a string literal with predefined entities. Predefined entities + * are: + *
literal is
+ * malformed.
+ */
+ private String decodePredefinedEntities(String literal) throws IllegalArgumentException {
+ int idx = literal.indexOf('&');
+ if (idx == -1) {
+ return literal;
+ }
+ int endIndex = -1;
+ StringBuffer buf = new StringBuffer();
+ buf.append(literal.substring(0, idx));
+ while (idx != -1) {
+ endIndex = literal.indexOf(';', idx);
+ if (endIndex == -1) {
+ throw new IllegalArgumentException(literal);
+ }
+ String entity = literal.substring(idx + 1, endIndex);
+ if (entity.equals("lt")) {
+ buf.append('<');
+ } else if (entity.equals("gt")) {
+ buf.append('>');
+ } else if (entity.equals("amp")) {
+ buf.append('&');
+ } else if (entity.equals("quot")) {
+ buf.append('"');
+ } else if (entity.equals("apos")) {
+ buf.append('\'');
+ } else {
+ throw new IllegalArgumentException(literal);
+ }
+ idx = literal.indexOf('&', idx + 1);
+ if (idx != -1) {
+ buf.append(literal.substring(endIndex + 1, idx));
+ }
+ }
+ // write remaining
+ buf.append(literal.substring(endIndex + 1));
+ return buf.toString();
}
}