diff --git a/changelog.html b/changelog.html index 82b2981587..67a84c62dd 100644 --- a/changelog.html +++ b/changelog.html @@ -61,6 +61,9 @@ Upcoming changes
  • Fixed a file handle leak in GET config.xml API call (issue 8042) +
  • + Fixed the redundant/incorrect encoding handling in XML configuration files. + (issue 4525)
  • Groovy script console is now syntax highlighted.
  • diff --git a/core/src/main/java/hudson/XmlFile.java b/core/src/main/java/hudson/XmlFile.java index a896890829..76cf01adbc 100644 --- a/core/src/main/java/hudson/XmlFile.java +++ b/core/src/main/java/hudson/XmlFile.java @@ -27,6 +27,7 @@ import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.xml.XppDriver; import com.thoughtworks.xstream.io.xml.XppReader; import hudson.model.Descriptor; import hudson.util.AtomicFileWriter; @@ -42,10 +43,12 @@ import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.Writer; @@ -123,9 +126,9 @@ public final class XmlFile { */ public Object read() throws IOException { LOGGER.fine("Reading "+file); - Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); + InputStream in = new BufferedInputStream(new FileInputStream(file)); try { - return xs.fromXML(r); + return xs.fromXML(in); } catch(StreamException e) { throw new IOException2("Unable to read "+file,e); } catch(ConversionException e) { @@ -133,7 +136,7 @@ public final class XmlFile { } catch(Error e) {// mostly reflection errors throw new IOException2("Unable to read "+file,e); } finally { - r.close(); + in.close(); } } @@ -145,9 +148,10 @@ public final class XmlFile { * if the XML representation is completely new. */ public Object unmarshal( Object o ) throws IOException { - Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8")); + InputStream in = new BufferedInputStream(new FileInputStream(file)); try { - return xs.unmarshal(new XppReader(r),o); + // TODO: expose XStream the driver from XStream + return xs.unmarshal(DEFAULT_DRIVER.createReader(in), o); } catch (StreamException e) { throw new IOException2("Unable to read "+file,e); } catch(ConversionException e) { @@ -155,7 +159,7 @@ public final class XmlFile { } catch(Error e) {// mostly reflection errors throw new IOException2("Unable to read "+file,e); } finally { - r.close(); + in.close(); } } @@ -295,6 +299,8 @@ public final class XmlFile { private static final SAXParserFactory JAXP = SAXParserFactory.newInstance(); + private static final XppDriver DEFAULT_DRIVER = new XppDriver(); + static { JAXP.setNamespaceAware(true); } diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index aff8dc7472..131c51b649 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -41,6 +41,7 @@ import hudson.util.AlternativeUiTextProvider; import hudson.util.AlternativeUiTextProvider.Message; import hudson.util.AtomicFileWriter; import hudson.util.IOException2; +import hudson.util.IOUtils; import jenkins.model.Jenkins; import org.apache.tools.ant.taskdefs.Copy; import org.apache.tools.ant.types.FileSet; @@ -460,8 +461,8 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet if (req.getMethod().equals("GET")) { // read checkPermission(EXTENDED_READ); - rsp.setContentType("application/xml;charset=UTF-8"); - getConfigFile().writeRawTo(rsp.getWriter()); + rsp.setContentType("application/xml"); + IOUtils.copy(getConfigFile().getFile(),rsp.getOutputStream()); return; } if (req.getMethod().equals("POST")) {