Question mark in filter expressions should match exactly one character (#672)

diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java
index 21d50f8..f1b5647 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java
@@ -19,30 +19,31 @@
 public class WildcardMatcherTest {
 
 	@Test
-	public void testEmpty() {
+	public void empty_expression_should_match_any_string() {
 		assertTrue(new WildcardMatcher("").matches(""));
 		assertFalse(new WildcardMatcher("").matches("abc"));
 	}
 
 	@Test
-	public void testExact() {
+	public void expressions_without_wildcards_should_match_exactly() {
 		assertTrue(new WildcardMatcher("abc/def.txt").matches("abc/def.txt"));
+		assertFalse(new WildcardMatcher("abc/def.txt").matches("/abc/def.txt"));
 	}
 
 	@Test
-	public void testCaseSensitive() {
+	public void should_match_case_sensitive() {
 		assertFalse(new WildcardMatcher("abcdef").matches("abcDef"));
 		assertFalse(new WildcardMatcher("ABCDEF").matches("AbCDEF"));
 	}
 
 	@Test
-	public void testQuote() {
+	public void should_not_use_regex_characters() {
 		assertFalse(new WildcardMatcher("rst.xyz").matches("rstAxyz"));
 		assertTrue(new WildcardMatcher("(x)+").matches("(x)+"));
 	}
 
 	@Test
-	public void testWildcards() {
+	public void asterix_should_match_any_number_of_any_character() {
 		assertTrue(new WildcardMatcher("*").matches(""));
 		assertTrue(new WildcardMatcher("*").matches("java/lang/Object"));
 		assertTrue(new WildcardMatcher("*Test").matches("jacoco/MatcherTest"));
@@ -50,20 +51,24 @@
 		assertTrue(new WildcardMatcher("Matcher*").matches("MatcherTest"));
 		assertTrue(new WildcardMatcher("a*b*a").matches("a-b-b-a"));
 		assertFalse(new WildcardMatcher("a*b*a").matches("alaska"));
-		assertTrue(new WildcardMatcher("Hello?orld").matches("HelloWorld"));
-		assertFalse(new WildcardMatcher("Hello?orld").matches("HelloWWWorld"));
-		assertTrue(new WildcardMatcher("?aco*").matches("jacoco"));
 	}
 
 	@Test
-	public void testMultiExpression() {
-		assertTrue(new WildcardMatcher("Hello:World").matches("World"));
+	public void questionmark_should_match_any_single_character() {
+		assertTrue(new WildcardMatcher("Hello?orld").matches("HelloWorld"));
+		assertFalse(new WildcardMatcher("Hello?orld").matches("Helloorld"));
+		assertFalse(new WildcardMatcher("Hello?orld").matches("HelloWWWorld"));
+	}
+
+	@Test
+	public void should_match_any_expression_when_multiple_expressions_are_given() {
 		assertTrue(new WildcardMatcher("Hello:World").matches("World"));
 		assertTrue(new WildcardMatcher("*Test:*Foo").matches("UnitTest"));
+		assertFalse(new WildcardMatcher("foo:bar").matches("foo:bar"));
 	}
 
 	@Test
-	public void testDollar() {
+	public void should_match_dollar_sign() {
 		assertTrue(new WildcardMatcher("*$*").matches("java/util/Map$Entry"));
 		assertTrue(new WildcardMatcher("*$$$*")
 				.matches("org/example/Enity$$$generated123"));
diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java b/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java
index 2b52d4b..14bbc2f 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java
@@ -14,9 +14,10 @@
 import java.util.regex.Pattern;
 
 /**
- * Matches strings against <code>?</code>/<code>*</code> wildcard expressions.
- * Multiple expressions can be separated with a colon (:). In this case the
- * expression matches if at least one part matches.
+ * Matches strings against glob like wildcard expressions where <code>?</code>
+ * matches any single character and <code>*</code> matches any number of any
+ * character. Multiple expressions can be separated with a colon (:). In this
+ * case the expression matches if at least one part matches.
  */
 public class WildcardMatcher {
 
@@ -47,7 +48,7 @@
 		for (final char c : expression.toCharArray()) {
 			switch (c) {
 			case '?':
-				regex.append(".?");
+				regex.append(".");
 				break;
 			case '*':
 				regex.append(".*");
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 4a02b4e..6c6a48e 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -31,6 +31,8 @@
   <li>Don't insert stackmap frames into class files with version &lt; 1.6,
       this fixes regression which was introduced in version 0.6.5
       (GitHub <a href="https://github.com/jacoco/jacoco/issues/667">#667</a>).</li>
+  <li>Question mark in filter expressions now correctly matches exactly one character
+      (GitHub <a href="https://github.com/jacoco/jacoco/issues/672">#672</a>).</li>
 </ul>
 
 <h2>Release 0.8.1 (2018/03/21)</h2>