add escaping of attribute values

git-svn-id: https://svn.apache.org/repos/asf/incubator/solr/trunk@395950 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Erik Hatcher 2006-04-21 17:10:12 +00:00
parent ced4e20ace
commit 765cd54cd8
3 changed files with 86 additions and 51 deletions

View File

@ -166,7 +166,7 @@ final public class XMLWriter {
writer.write(' ');
writer.write(name);
writer.write("=\"");
writer.write(val);
XML.escapeAttributeValue(val, writer);
writer.write('"');
}
}
@ -177,12 +177,11 @@ final public class XMLWriter {
writer.write('<');
writer.write(tag);
if (name!=null) {
writer.write(" name=\"");
writer.write(name);
writeAttr("name", name);
if (closeTag) {
writer.write("\"/>");
writer.write("/>");
} else {
writer.write("\">");
writer.write(">");
}
} else {
if (closeTag) {

View File

@ -34,6 +34,10 @@ public class XML {
private static final String[] chardata_escapes=
{"#0;","#1;","#2;","#3;","#4;","#5;","#6;","#7;","#8;",null,null,"#11;","#12;",null,"#14;","#15;","#16;","#17;","#18;","#19;","#20;","#21;","#22;","#23;","#24;","#25;","#26;","#27;","#28;","#29;","#30;","#31;",null,null,null,null,null,null,"&amp;",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"&lt;"};
private static final String[] attribute_escapes=
{"#0;","#1;","#2;","#3;","#4;","#5;","#6;","#7;","#8;",null,null,"#11;","#12;",null,"#14;","#15;","#16;","#17;","#18;","#19;","#20;","#21;","#22;","#23;","#24;","#25;","#26;","#27;","#28;","#29;","#30;","#31;",null,null,"&quot;",null,null,null,"&amp;",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"&lt;"};
/*****************************************
#Simple python script used to generate the escape table above. -YCS
@ -71,42 +75,14 @@ public class XML {
* @throws IOException
*/
public static void escapeCharData(String str, Writer out) throws IOException {
int start=0;
// "n" was used for counting the chars added to out...
// removed cause it wasn't really useful so far.
// int n=0;
for (int i=start; i<str.length(); i++) {
char ch = str.charAt(i);
// since I already received the char, what if I put it into
// a char array and wrote that to the stream instead of the
// string? (would cause extra GC though)
String subst=null;
if (ch<chardata_escapes.length) {
subst=chardata_escapes[ch];
}
if (subst != null) {
if (start<i) {
// out.write(str.substring(start,i));
out.write(str, start, i-start);
// n+=i-start;
}
out.write(subst);
// n+=subst.length();
start=i+1;
}
}
if (start==0) {
out.write(str);
// n += str.length();
} else if (start<str.length()) {
// out.write(str.substring(start));
out.write(str, start, str.length()-start);
// n += str.length()-start;
}
// return n;
escape(str, out, chardata_escapes);
}
public static void escapeAttributeValue(String str, Writer out) throws IOException {
escape(str, out, attribute_escapes);
}
public final static void writeXML(Writer out, String tag, String val) throws IOException {
out.write('<');
out.write(tag);
@ -151,7 +127,7 @@ public class XML {
out.write(' ');
out.write(attrs[i++].toString());
out.write("=\"");
out.write(attrs[i].toString());
escapeAttributeValue(attrs[i].toString(), out);
out.write("\"");
}
if (val == null) {
@ -164,4 +140,42 @@ public class XML {
out.write('>');
}
}
private static void escape(String str, Writer out, String[] escapes) throws IOException {
int start=0;
// "n" was used for counting the chars added to out...
// removed cause it wasn't really useful so far.
// int n=0;
for (int i=start; i<str.length(); i++) {
char ch = str.charAt(i);
// since I already received the char, what if I put it into
// a char array and wrote that to the stream instead of the
// string? (would cause extra GC though)
String subst=null;
if (ch<escapes.length) {
subst=escapes[ch];
}
if (subst != null) {
if (start<i) {
// out.write(str.substring(start,i));
out.write(str, start, i-start);
// n+=i-start;
}
out.write(subst);
// n+=subst.length();
start=i+1;
}
}
if (start==0) {
out.write(str);
// n += str.length();
} else if (start<str.length()) {
// out.write(str.substring(start));
out.write(str, start, str.length()-start);
// n += str.length()-start;
}
// return n;
}
}

View File

@ -18,6 +18,14 @@ package org.apache.solr;
import org.apache.solr.request.*;
import org.apache.solr.util.*;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.IOException;
import java.io.StringWriter;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
/**
* Tests some basic functionality of Solr while demonstrating good
@ -25,9 +33,9 @@ import org.apache.solr.util.*;
*/
public class BasicFunctionalityTest extends AbstractSolrTestCase {
public String getSchemaFile() { return "schema.xml"; }
public String getSchemaFile() { return "schema.xml"; }
public String getSolrConfigFile() { return "solrconfig.xml"; }
public void setUp() throws Exception {
// if you override setUp or tearDown, you better call
// the super classes version
@ -54,13 +62,13 @@ public class BasicFunctionalityTest extends AbstractSolrTestCase {
adoc("id", "42", "val_s", "aa;bb"));
assertU("does commit work?",
commit());
assertQ("backslash escaping semicolon",
req("id:42 AND val_s:aa\\;bb")
,"//*[@numFound='1']"
,"//int[@name='id'][.='42']"
);
assertQ("quote escaping semicolon",
req("id:42 AND val_s:\"aa;bb\"")
,"//*[@numFound='1']"
@ -77,9 +85,9 @@ public class BasicFunctionalityTest extends AbstractSolrTestCase {
assertQ(req("id:42")
,"//*[@numFound='0']"
);
// test allowDups default of false
assertU(adoc("id", "42", "val_s", "AAA"));
assertU(adoc("id", "42", "val_s", "BBB"));
assertU(commit());
@ -138,16 +146,30 @@ public class BasicFunctionalityTest extends AbstractSolrTestCase {
assertQ(req("id:[0 TO 99]")
,"//*[@numFound='2']"
);
}
public void testXMLWriter() throws Exception {
SolrQueryResponse rsp = new SolrQueryResponse();
rsp.add("\"quoted\"", "\"value\"");
StringWriter writer = new StringWriter(32000);
XMLWriter.writeResponse(writer,req("foo"),rsp);
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
builder.parse(new ByteArrayInputStream
(writer.toString().getBytes("UTF-8")));
}
// /** this doesn't work, but if it did, this is how we'd test it. */
// public void testOverwriteFalse() {
// assertU(adoc("id", "overwrite", "val_s", "AAA"));
// assertU(commit());
// assertU(add(doc("id", "overwrite", "val_s", "BBB")
// ,"allowDups", "false"
// ,"overwriteCommitted","false"
@ -159,6 +181,6 @@ public class BasicFunctionalityTest extends AbstractSolrTestCase {
// ,"//str[.='AAA']"
// );
// }
}