escape special xml characters

This commit is contained in:
REAndroid 2023-04-20 17:47:11 +02:00
parent 340f8d07f9
commit 2eff5832d7
4 changed files with 52 additions and 4 deletions

View File

@ -34,10 +34,12 @@ public class ResXmlDocumentSerializer implements ResXmlPullParser.DocumentLoaded
private final XmlSerializer serializer; private final XmlSerializer serializer;
private final XmlParserToSerializer parserToSerializer; private final XmlParserToSerializer parserToSerializer;
private boolean validateXmlNamespace; private boolean validateXmlNamespace;
private String mCurrentPath;
public ResXmlDocumentSerializer(ResXmlPullParser parser){ public ResXmlDocumentSerializer(ResXmlPullParser parser){
this.parser = parser; this.parser = parser;
this.serializer = new KXmlSerializer(); this.serializer = new KXmlSerializer();
this.parserToSerializer = new XmlParserToSerializer(parser, serializer); this.parserToSerializer = new XmlParserToSerializer(parser, serializer);
this.parser.setDocumentLoadedListener(this);
} }
public ResXmlDocumentSerializer(Decoder decoder){ public ResXmlDocumentSerializer(Decoder decoder){
this(new ResXmlPullParser(decoder)); this(new ResXmlPullParser(decoder));
@ -61,9 +63,14 @@ public class ResXmlDocumentSerializer implements ResXmlPullParser.DocumentLoaded
this.parser.setInput(inputStream, null); this.parser.setInput(inputStream, null);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
this.serializer.setOutput(writer); this.serializer.setOutput(writer);
try{
this.parserToSerializer.write(); this.parserToSerializer.write();
}catch (Exception ex){
throw getError(ex);
}
writer.close(); writer.close();
outputStream.close(); outputStream.close();
mCurrentPath = null;
} }
} }
public void write(InputStream inputStream, File file) public void write(InputStream inputStream, File file)
@ -72,11 +79,13 @@ public class ResXmlDocumentSerializer implements ResXmlPullParser.DocumentLoaded
if(dir != null && !dir.exists()){ if(dir != null && !dir.exists()){
dir.mkdirs(); dir.mkdirs();
} }
mCurrentPath = String.valueOf(file);
FileOutputStream outputStream = new FileOutputStream(file); FileOutputStream outputStream = new FileOutputStream(file);
write(inputStream, outputStream); write(inputStream, outputStream);
} }
public void write(ResXmlDocument xmlDocument, File file) public void write(ResXmlDocument xmlDocument, File file)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
mCurrentPath = String.valueOf(file);
File dir = file.getParentFile(); File dir = file.getParentFile();
if(dir != null && !dir.exists()){ if(dir != null && !dir.exists()){
dir.mkdirs(); dir.mkdirs();
@ -116,6 +125,27 @@ public class ResXmlDocumentSerializer implements ResXmlPullParser.DocumentLoaded
namespaceValidator.validate(); namespaceValidator.validate();
return resXmlDocument; return resXmlDocument;
} }
private IOException getError(Exception exception){
String path = mCurrentPath;
if(exception instanceof IOException){
String msg = path + ":" + exception.getMessage();
IOException ioException = new IOException(msg);
ioException.setStackTrace(exception.getStackTrace());
Throwable cause = ioException.getCause();
if(cause != null){
ioException.initCause(cause);
}
return ioException;
}
String msg = path + ":" + exception.getClass() + ":" + exception.getMessage();
IOException otherException = new IOException(msg);
otherException.setStackTrace(exception.getStackTrace());
Throwable cause = otherException.getCause();
if(cause != null){
otherException.initCause(cause);
}
return otherException;
}
private static Decoder createDecoder(ApkModule apkModule){ private static Decoder createDecoder(ApkModule apkModule){
Decoder decoder = Decoder.create(apkModule.getTableBlock()); Decoder decoder = Decoder.create(apkModule.getTableBlock());

View File

@ -16,6 +16,8 @@
package com.reandroid.arsc.chunk.xml; package com.reandroid.arsc.chunk.xml;
import com.reandroid.arsc.decoder.ValueDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -43,7 +45,11 @@ public class ParserEventList implements Iterator<ParserEvent> {
return getElement().getTag(); return getElement().getTag();
} }
if(type == ParserEvent.TEXT){ if(type == ParserEvent.TEXT){
return ((ResXmlTextNode)getXmlNode()).getText(); String text = ((ResXmlTextNode)getXmlNode()).getText();
if(text == null){
text = "";
}
return ValueDecoder.escapeSpecialCharacter(text);
} }
return null; return null;
} }

View File

@ -70,10 +70,18 @@ public class Decoder {
return ValueDecoder.decode(getEntryStore(), getCurrentPackageId(), value); return ValueDecoder.decode(getEntryStore(), getCurrentPackageId(), value);
} }
public String decodeAttributeValue(AttributeValue attributeValue){ public String decodeAttributeValue(AttributeValue attributeValue){
return decodeAttributeValue(attributeValue, true);
}
public String decodeAttributeValue(AttributeValue attributeValue, boolean escapeStartChar){
if(attributeValue == null){ if(attributeValue == null){
return null; return null;
} }
return ValueDecoder.decode(getEntryStore(), getCurrentPackageId(), attributeValue); String result = ValueDecoder.decode(getEntryStore(), getCurrentPackageId(), attributeValue);
if(!escapeStartChar || result == null || result.length() == 0
|| attributeValue.getValueType() != ValueType.STRING){
return result;
}
return ValueDecoder.escapeSpecialCharacter(result);
} }
private EntryStore getEntryStore() { private EntryStore getEntryStore() {
return entryStore; return entryStore;

View File

@ -202,7 +202,11 @@ import java.util.Objects;
public String getValueAsString(){ public String getValueAsString(){
StringItem stringItem = getDataAsPoolString(); StringItem stringItem = getDataAsPoolString();
if(stringItem!=null){ if(stringItem!=null){
return stringItem.getHtml(); String value = stringItem.getHtml();
if(value == null){
value = "";
}
return value;
} }
return null; return null;
} }