Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions Sources/Actions/Admin/Maintenance.php
Original file line number Diff line number Diff line change
Expand Up @@ -2300,13 +2300,21 @@ protected static function parseIntegrationHook(string $hook, string $rawData): a
protected static function getDefinedFunctionsInFile(string $file): array
{
$source = file_get_contents($file);
// token_get_all() is too slow so use a nice little regex instead.
preg_match_all('/\bnamespace\s++((?P>label)(?:\\\(?P>label))*+)\s*+;|\bclass\s++((?P>label))[\w\s]*+{|\bfunction\s++((?P>label))\s*+\(.*?\)[:\|\w\s]*+{(?(DEFINE)(?<label>[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*+))/is', $source, $matches, PREG_SET_ORDER);

if (!str_contains($source, 'function')) {
return [];
}

// Remove multiline comments so regex does not
// match fake functions/classes inside them.
$source = preg_replace('~//[^\h]+|/\*.*?\*/~s', '', $source);
Comment on lines +2308 to +2310

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Remove multiline comments so regex does not
// match fake functions/classes inside them.
$source = preg_replace('~//[^\h]+|/\*.*?\*/~s', '', $source);
// Remove multiline comments so regex does not
// match fake functions/classes inside them.
$source = Config::stripPhpComments($source);

This would produce more thorough and reliable results.

Can I get you to submit a follow-up PR making this change, @live627?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't noticed that function before now. I'm testing it now. It's quite a bit slower: the one with the token takes 0.43s, while the custom algorithm takes 0.38s. The one in this branch takes 0.08s.

That custom implementation also missed a function.

(new regex = mine, old regex = your suggested change without the tokenizer)

Files:        1599
Iterations:   1

New regex total: 79.910 ms
Old regex total: 378.003 ms

New regex avg:   79.910 ms
Old regex avg:   378.003 ms

Speedup:         4.73x (new regex faster)

New regex count: 4420
Old regex count: 4419

Differences detected:

../../smf2.1/sources\Subs-Compat.php
  New regex only:
    + package_crypt

$functions = [];
$namespace = '';
$class = '';

// token_get_all() is too slow so use a nice little regex instead.
preg_match_all('/\b(?:namespace\s+((?P>label)(?:\\\(?P>label))*+)\s*;|(?:class\s+((?P>label))(?:[\s,]|\\\\|(?P>label))*+|function\s+((?P>label))\s*\([^)]*\)\s*(?::[^{]+)?){)(?(DEFINE)(?<label>[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*+))/i', $source, $matches, PREG_SET_ORDER);

foreach ($matches as $match) {
if (!empty($match[1])) {
$namespace = $match[1] . '\\';
Expand Down
Loading