Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-10346] thread-safety problem when computing fingerprints
(cherry picked from commit 3c09a0c)

Conflicts:

	changelog.html
  • Loading branch information
kutzi authored and vjuranek committed Aug 17, 2011
1 parent ef2c8a7 commit e436a28
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 9 deletions.
7 changes: 5 additions & 2 deletions changelog.html
Expand Up @@ -56,11 +56,14 @@
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=bug>
Tests not recognized as failed if test initialization failed
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-6700">issue 6700</a>)
Fixed a race condition in the fingerprint computation
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-10346">issue 10346</a>)
<li class=bug>
Fixed a race condition in the remoting that can break the pipe support
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-8703">issue 8703</a>)
<li class=bug>
Tests not recognized as failed if test initialization failed
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-6700">issue 6700</a>)
</ul>
</div><!--=TRUNK-END=-->

Expand Down
9 changes: 2 additions & 7 deletions core/src/main/java/hudson/Util.java
Expand Up @@ -500,11 +500,6 @@ public static String removeTrailingSlash(String s) {
else return s;
}

/**
* Write-only buffer.
*/
private static final byte[] garbage = new byte[8192];

/**
* Computes MD5 digest of the given input stream.
*
Expand All @@ -519,7 +514,7 @@ public static String getDigestOf(InputStream source) throws IOException {

DigestInputStream in =new DigestInputStream(source,md5);
try {
while(in.read(garbage)>0)
while(in.read(new byte[1024])>0)
; // simply discard the input
} finally {
in.close();
Expand Down Expand Up @@ -699,7 +694,7 @@ public static String encode(String s) {
OutputStreamWriter w = new OutputStreamWriter(buf,"UTF-8");

for (int i = 0; i < s.length(); i++) {
int c = (int) s.charAt(i);
int c = s.charAt(i);
if (c<128 && c!=' ') {
out.append((char) c);
} else {
Expand Down
53 changes: 53 additions & 0 deletions core/src/test/java/hudson/UtilTest.java
Expand Up @@ -32,6 +32,8 @@
import java.io.ByteArrayOutputStream;
import java.io.File;

import org.jvnet.hudson.test.Bug;

import hudson.util.StreamTaskListener;

/**
Expand Down Expand Up @@ -177,4 +179,55 @@ public void TestEscape() {
assertEquals("&quot;&#039;", Util.escape("'\""));
assertEquals("&nbsp; ", Util.escape(" "));
}

/**
* Compute 'known-correct' digests and see if I still get them when computed concurrently
* to another digest.
*/
@Bug(10346)
public void testDigestThreadSafety() throws InterruptedException {
String a = "abcdefgh";
String b = "123456789";

String digestA = Util.getDigestOf(a);
String digestB = Util.getDigestOf(b);

DigesterThread t1 = new DigesterThread(a, digestA);
DigesterThread t2 = new DigesterThread(b, digestB);

t1.start();
t2.start();

t1.join();
t2.join();

if (t1.error != null) {
fail(t1.error);
}
if (t2.error != null) {
fail(t2.error);
}
}

private static class DigesterThread extends Thread {
private String string;
private String expectedDigest;

private String error;

public DigesterThread(String string, String expectedDigest) {
this.string = string;
this.expectedDigest = expectedDigest;
}

public void run() {
for (int i=0; i < 1000; i++) {
String digest = Util.getDigestOf(this.string);
if (!this.expectedDigest.equals(digest)) {
this.error = "Expected " + this.expectedDigest + ", but got " + digest;
break;
}
}
}
}
}

0 comments on commit e436a28

Please sign in to comment.