-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKeywordEnhancer.php
More file actions
111 lines (91 loc) · 5.32 KB
/
KeywordEnhancer.php
File metadata and controls
111 lines (91 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
namespace PHPWatch\PHPCommitBuilder;
class KeywordEnhancer {
protected const array CODIFY_PATTERNS = [
'/\b(?<!`)(?:zend|php)_[a-z_]+\(\)(?!`)/i', // zend_foo_bar()
'/\b(?<!`)(?:zend|php|_php)_[a-z_*]+\b(?![`.(=])\*?/i', // zend_foo_bar
'/(?<![`>()-])\bext\/[a-z_\d\/-]+\.phpt\b(?![`])/i', // ext/test/test/test.phpt
'/\b(?<![`\/])[a-z][a-z\d_-]+(.stubs?)?\.(phpt?|c|h)(?![`.?])/', // run-tests.php / foo.stub.php foo.stubs.php / test-foo-bar.phpt,
'/\b(?<!`)ext\/[a-z_]+\b(?![`\/])/', // ext-names
'/\b(?<![`:])__[a-z][a-zA-Z\d_]+\(\)(?![`ws])/', // __debugInfo()
'/\b(?<!`)[A-Za-z][A-Z\\\\a-z\d]+::(?:__)?[a-z][A-Za-z\d_]+\(\)(?![`\/-])/', // Class::methods()
'/\b(?<!`)[A-Z][A-Za-z]+::(?:__)[a-z][A-Za-z\d_]+(?![`\/-])\b(?![)(])/', // Class::__magicMethods
'/\b(?<!`)[A-Z][A-Za-z]+::[A-Z][A-Z_\d]+\b(?![`\/(])/', // Class::CONSTANTS
'/\b(?<![`\\\\])[A-Z][A-Z\\\\a-z]+::[a-z][A-Za-z_\d]+\b(?![`\/(])/', // Class::constants
'/\b(?<!`-)[a-z]+_[a-z]+(?:_[a-z_]+)?\(\)(?![`\/])/', // Functions with underscores and ()
'/\b(?<![`>])[a-z_][a-z][a-z\d_]+\*?\(\)(?![`.>\/-])/', // Functions with underscores and ()
'/\b(?<!`)(?:ldap|ftp|array|mb|stream|open|hash|xml|proc|pcntl|curl|intl|date|grapheme|socket|stream)_[a-z_]+\d?\b(?![`\/])/', // Functions with underscores and no ()
'/\b(?<!`)(xleak|xfail|skipif)\b(?![`\/])/i', // xleak
'/(?<![`>()-])--[a-z][a-z-]+(?![`])/i', // --flags, --flags-and-more
'/\b(?<![`>:-])__[A-Z\d_]+(?![`])/i', // __PROPERTY__
'/(?<=\s)(?<![`>-])\\\\[A-Z][a-z]+\\\\[A-Z][A-Za-z]+(?![`])\b/', // Stricter, class name like \Dom\HTMLDocument
'/\b(?<![`>()-])(?:(main|ext|Zend|tests|win32|scripts|sapi|pear|docs|build)\/(?:[a-z\d\/_]+))(?:\.(c|php|phpt|yml|yaml|cpp|m4|txt|w32|h))(?::\d+)?(?![`\w])/i', // files in php-src
'/\b(?<!`)(?:(DATE|SOAP|SO|TCP|SOCK|FILTER|XML|FTP|CURL|CURLOPT|CURLE|CURLINFO|GREP|X509|ZEND|USE_ZEND|TEST|HASH))_[A-Z_\d]+\b(?![`\/(*_\S])/', // CONSTANTS (with fixed prefixes)
'/\b(?<![`\w])(HASH|DATE|MHASH)_[A-Z_]+_\*(?![`\/(\w\S])/', // Const names with * at the end
'/(?<![`\w])#\[\\\\?[A-Z][A-Za-z\d_]+](?![`\w\/])/', // Attributes
'/\B(?<![`\S\w])\$[a-z_\d]+(?![`\w\S])/', // Variable names, lowercase
];
public static function enhance(string $inputText): string {
return static::format($inputText);
}
public static function enhanceCommit(string $commitSubject, string $shortHash): string {
return static::format($commitSubject, $shortHash);
}
private static function format(string $inputText, ?string $shortHash = null): string {
$inputText = static::linkToBug($inputText);
$inputText = static::linkToGitHub($inputText, $shortHash);
$inputText = static::codifyText($inputText);
$inputText = static::linkToSecurityAnnouncements($inputText);
return $inputText;
}
private static function linkToBug(string $subject): string {
if (preg_match('/#[5-9]\d{4}/', $subject)) {
return preg_replace('/#(\d{5})/', '[#$1](https://bugs.php.net/bug.php?id=$1)', $subject);
}
return $subject;
}
private static function linkToGitHub(string $subject, ?string $shortHash = null): string {
$subject = preg_replace('/\b(?<!\[)GH-(\d{3,6})\b/', "[GH-$1](https://github.com/php/php-src/issues/$1)", $subject);
$subject = preg_replace('/\b(?<!\[)GH-(\d{3,6})\b/', "[GH-$1](https://github.com/php/php-src/issues/$1)", $subject);
$subject = preg_replace('/(?<![`>()\b\d\S\[-])#([1-3]\d\d\d\d)\b(?![`-])/', "[GH-$1](https://github.com/php/php-src/issues/$1)", $subject);
$subject = preg_replace(
'/\b(?<!\[)(([a-fA-F\d]){8})([a-fA-F\d]){4,32}\b/',
"[$1](https://github.com/php/php-src/commit/$0)",
$subject
);
if (preg_match('/(?<!\[)\(#(\d{3,6})\)$/', $subject)) {
return preg_replace('/\(#(\d{3,6})\)$/', "in [GH-$1](https://github.com/php/php-src/pull/$1)", $subject);
}
if (preg_match('/Closes GH-(\d{3,6})\D?/', $subject, $matches)) {
$subject .= sprintf(" in [GH-%d](https://github.com/php/php-src/pull/%d)", $matches[1], $matches[1]);
return $subject;
}
if ($shortHash) {
return $subject . sprintf(' in [%s](https://github.com/php/php-src/commit/%s)', $shortHash, $shortHash);
}
return $subject;
}
private static function linkToSecurityAnnouncements(string $inputText): string {
if (preg_match('/(CVE-20\d\d-\d{1,5})\D/i', $inputText)) {
$inputText = preg_replace(
'/(CVE-20\d\d-\d{1,5})(\D)/i',
"[$1](https://nvd.nist.gov/vuln/detail/$1)$2",
$inputText
);
}
if (preg_match('/(GHSA-[a-z\d-]{14})(\W)/i', $inputText)) {
$inputText = preg_replace(
'/(GHSA-[a-z\d-]{14})(\W)/',
"[$1](https://github.com/php/php-src/security/advisories/$1)$2",
$inputText
);
}
return $inputText;
}
private static function codifyText(string $input): string {
foreach (static::CODIFY_PATTERNS as $pattern) {
$input = preg_replace($pattern, '`$0`', $input);
}
return $input;
}
}