With PHP 7.3, the hash (#) is being escaped by preg_quote().
While normally that doesnt have much impact and normal operations
continue working perfectly... when the results of the function are
used to match against the same string... they don't match anymore.
Have found a couple of there double-uses in core and this
commit fixes them. Covered with tests.
protected function build_regexp($expression, $tokens) {
// Replace to temp (and preg_quote() safe) placeholders
foreach ($tokens as $token) {
- $expression = preg_replace('~' . preg_quote($token, '~') . '~', '#@@#@@#', $expression, 1);
+ $expression = preg_replace('~' . preg_quote($token, '~') . '~', '%@@%@@%', $expression, 1);
}
// quote the expression
$expression = preg_quote($expression, '~');
// Replace all the placeholders
- $expression = preg_replace('~#@@#@@#~', '(.*)', $expression);
+ $expression = preg_replace('~%@@%@@%~', '(.*)', $expression);
return '~' . $expression . '~';
}
}
// But the original log has been kept unmodified by the process() call.
$this->assertEquals($originallog, $log);
}
+
+ public function test_build_regexp() {
+ $original = 'Any (string) with [placeholders] like {this} and {this}. [end].';
+ $expectation = '~Any \(string\) with (.*) like (.*) and (.*)\. (.*)\.~';
+
+ $lr = new restore_log_rule('this', 'doesnt', 'matter', 'here');
+ $class = new ReflectionClass('restore_log_rule');
+
+ $method = $class->getMethod('extract_tokens');
+ $method->setAccessible(true);
+ $tokens = $method->invoke($lr, $original);
+
+ $method = $class->getMethod('build_regexp');
+ $method->setAccessible(true);
+ $this->assertSame($expectation, $method->invoke($lr, $original, $tokens));
+ }
}
$ignorecase = 'i';
}
} else {
- $expectedanswer = str_replace('*', '#####', $expectedanswer);
+ $expectedanswer = str_replace('*', '%@@%@@%', $expectedanswer);
$expectedanswer = preg_quote($expectedanswer, '/');
- $expectedanswer = str_replace('#####', '.*', $expectedanswer);
+ $expectedanswer = str_replace('%@@%@@%', '.*', $expectedanswer);
}
// see if user typed in any of the correct answers
if ((!$this->lesson->custom && $this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) or ($this->lesson->custom && $answer->score > 0) ) {