MDL-43000 shortanswer qtype: handle patterns with many *s

Teachers were typing patterns like
********************************<em>****************************</em>
which translates into a pattern like .*.*.*.*, which is very inefficient
to try to match, althought it is equivalent ot a single .*. At a certain
point preg was just giving up.

Since people actually do this, we should simplify the regex by treating
runs of * like a single *.
This commit is contained in:
Tim Hunt
2013-11-22 11:32:09 +00:00
parent f7434db109
commit 5dbfbc82cf
2 changed files with 10 additions and 2 deletions
+4 -2
View File
@@ -92,8 +92,10 @@ class qtype_shortanswer_question extends question_graded_by_strategy
$pattern = self::safe_normalize($pattern);
$string = self::safe_normalize($string);
// Break the string on non-escaped asterisks.
$bits = preg_split('/(?<!\\\\)\*/', $pattern);
// Break the string on non-escaped runs of asterisks.
// ** is equivalent to *, but people were doing that, and with many *s it breaks preg.
$bits = preg_split('/(?<!\\\\)\*+/', $pattern);
// Escape regexp special characters in the bits.
$escapedbits = array();
foreach ($bits as $bit) {
@@ -132,6 +132,12 @@ class qtype_shortanswer_question_test extends advanced_testcase {
'0', '*0*', false));
}
public function test_compare_string_with_wildcard_many_stars() {
// Test the classic PHP problem case with '0'.
$this->assertTrue((bool)qtype_shortanswer_question::compare_string_with_wildcard(
'<em></em>', '***********************************<em>***********************************</em>', false));
}
public function test_is_complete_response() {
$question = test_question_maker::make_question('shortanswer');