Skip to content

Commit

Permalink
[FIXED JENKINS-23531] ignore invalid xml entities
Browse files Browse the repository at this point in the history
  • Loading branch information
nilleb committed Mar 27, 2015
1 parent ffafe38 commit f8b7527
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 7 deletions.
90 changes: 90 additions & 0 deletions src/main/java/hudson/plugins/mstest/ContentCorrector.java
@@ -0,0 +1,90 @@
package hudson.plugins.mstest;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Created by ivo on 27/03/2015.
*/
public class ContentCorrector
{
private String file;

public ContentCorrector(String file)
{
this.file = file;
}

public String fix() throws IOException
{
String filename = Integer.toString(randInt(1000, 1000000)) + ".rnd";
File inFile = new File(file);
File parent = inFile.getParentFile();
File outfile = new File(parent, filename);
PrintWriter out = new PrintWriter(outfile);
BufferedReader in = new BufferedReader(new FileReader(inFile));
String line = in.readLine();
while (line != null) {
line = stripIllegalEntities(stripIllegalCharacters(line));
out.println(line);
line = in.readLine();
}
in.close();
out.close();
return outfile.getAbsolutePath();
}

private String stripIllegalCharacters(String line)
{
String xml10pattern = "[^"
+ "\u0009\r\n"
+ "\u0020-\uD7FF"
+ "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff"
+ "]";
String xml11pattern = "[^"
+ "\u0001-\uD7FF"
+ "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff"
+ "]+";
return line.replaceAll(xml10pattern, "").replaceAll(xml11pattern, "");
}

private String stripIllegalEntities(String line)
{
final String pattern = "(?<entity>&#x(?<char>[0-9A-Ca-c]{1,4});)";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(line);

while (m.find()) {
long c = Long.parseLong(m.group("char"), 16);
if (!isAllowed(c)) {
line = new StringBuilder(line).replace(m.start("entity"), m.end("entity"), "").toString();
m = p.matcher(line);
}
}
return line;
}

public boolean isAllowed(long c)
{
return c == 9 || c == 0xA || c == 0xD || (c > 0x20 && c < 0xD7FF) || (c > 0xE000 && c < 0xFFFD) || (c > 0x10000 && c < 0x10FFFF);
}

public static int randInt(int min, int max) {

// NOTE: Usually this should be a field rather than a method
// variable so that it is not re-seeded every call.
Random rand = new Random();

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;

return randomNum;
}
}
3 changes: 2 additions & 1 deletion src/main/java/hudson/plugins/mstest/MSTestTransformer.java
Expand Up @@ -60,7 +60,8 @@ public Boolean invoke(File ws, VirtualChannel channel) throws IOException {
for (String mstestFile : mstestFiles) {
listener.getLogger().println("MSTest: " + mstestFile);
try {
unitReportTransformer.transform(mstestFile, junitOutputPath, listener);
String fixed = new ContentCorrector(mstestFile).fix();
unitReportTransformer.transform(fixed, junitOutputPath, listener);
} catch (TransformerException te) {
throw new IOException(
"MSTest: Could not transform the MSTest report. Please report this issue to the plugin author", te);
Expand Down
29 changes: 23 additions & 6 deletions src/test/java/hudson/plugins/mstest/MSTestTransformerTest.java
Expand Up @@ -5,14 +5,14 @@
import hudson.model.BuildListener;
import hudson.remoting.VirtualChannel;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.io.*;
import java.nio.file.Files;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

/**
Expand All @@ -23,8 +23,6 @@
public class MSTestTransformerTest extends TestHelper{


protected File parentFile;
protected FilePath workspace;
private BuildListener buildListener;
private Mockery context;
private Mockery classContext;
Expand Down Expand Up @@ -53,7 +51,7 @@ public void tearDown() throws Exception {


@Test
public void testReturnWhenNoTRXFileisFound() throws Exception {
public void testReturnWhenNoTRXFileIsFound() throws Exception {
classContext.checking(new Expectations() {
{
ignoring(buildListener).getLogger();
Expand All @@ -65,4 +63,23 @@ public void testReturnWhenNoTRXFileisFound() throws Exception {
Boolean result = transformer.invoke(parentFile, virtualChannel);
assertFalse("The archiver did not return false when it could not find any files", result);
}


@Ignore
@Test
public void testInvalidXmlCharacters() throws Exception {
classContext.checking(new Expectations() {
{
ignoring(buildListener).getLogger();
}
});
final String testPath = "xmlentities-forged.xml";
File testFile = new File(parentFile, testPath);
if (testFile.exists())
testFile.delete();
InputStream testStream = this.getClass().getResourceAsStream("JENKINS-23531-xmlentities-forged.trx");
Files.copy(testStream, testFile.toPath());
transformer = new MSTestTransformer(testPath, converter, buildListener);
transformer.invoke(parentFile, virtualChannel);
}
}

0 comments on commit f8b7527

Please sign in to comment.