Skip to content

Commit 9cc48b3

Browse files
committed
Bug-fix.
Changelog excerpt: - Changed the normalise method's visibility from private to public in order to avoid raising fatal errors when using CLI mode's url_sig command.
1 parent a8a3642 commit 9cc48b3

File tree

2 files changed

+107
-103
lines changed

2 files changed

+107
-103
lines changed

Changelog.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,9 @@ __*Why "v3.0.0" instead of "v1.0.0?"*__ Prior to phpMussel v3, the "phpMussel Co
169169

170170
### v3.6.1
171171

172-
- [2025.03.24]: Applied entropy limits to some additional detections.
172+
#### Bugs fixed.
173173
- [2025.03.28]: Adjusted debug array code to avoid dynamic properties.
174+
- [2025.03.28]: Changed the normalise method's visibility from private to public in order to avoid raising fatal errors when using CLI mode's url_sig command.
175+
176+
#### Other changes.
177+
- [2025.03.24]: Applied entropy limits to some additional detections.

src/Scanner.php

+102-102
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,108 @@ public function atHit(string $Hash, int $Size = -1, string $Name = '', string $T
708708
$this->Loader->InstanceCache['CheckWasLast'] = false;
709709
}
710710

711+
/**
712+
* Does some more complex decoding and normalisation work on strings.
713+
*
714+
* @param string $str The string to be decoded/normalised.
715+
* @param bool $html If true, "style" and "script" tags will be stripped from
716+
* the input string (optional; defaults to false).
717+
* @param bool $decode If false, the input string will be normalised, but not
718+
* decoded; If true, the input string will be normalised *and* decoded.
719+
* Optional; Defaults to false.
720+
* @return string The decoded/normalised string.
721+
*/
722+
public function normalise(string $str, bool $html = false, bool $decode = false): string
723+
{
724+
/** Fire event: "atStartOf_normalise". */
725+
$this->Loader->Events->fireEvent('atStartOf_normalise');
726+
727+
$ostr = '';
728+
if ($decode) {
729+
$ostr .= $str;
730+
while (true) {
731+
if (
732+
function_exists('gzinflate') &&
733+
$c = preg_match_all('/(gzinflate\s*\\(\s*["\'])(.{1,4096})(,\d)?(["\']\s*\\))/i', $str, $matches)
734+
) {
735+
for ($i = 0; $c > $i; $i++) {
736+
$str = str_ireplace(
737+
$matches[0][$i],
738+
'"' . gzinflate($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[4][$i])) . '"',
739+
$str
740+
);
741+
}
742+
continue;
743+
}
744+
if ($c = preg_match_all(
745+
'/(base64_decode|decode_base64|base64\.b64decode|atob|Base64\.decode64)(\s*' .
746+
'\\(\s*["\'\`])([\da-z+\/]{4})*([\da-z+\/]{4}|[\da-z+\/]{3}=|[\da-z+\/]{2}==)(["\'\`]' .
747+
'\s*\\))/i',
748+
$str,
749+
$matches
750+
)) {
751+
for ($i = 0; $c > $i; $i++) {
752+
$str = str_ireplace(
753+
$matches[0][$i],
754+
'"' . base64_decode($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i] . $matches[2][$i]), $matches[5][$i])) . '"',
755+
$str
756+
);
757+
}
758+
continue;
759+
}
760+
if ($c = preg_match_all(
761+
'/(str_rot13\s*\\(\s*["\'])([^\'"\\(\\)]{1,4096})(["\']\s*\\))/i',
762+
$str,
763+
$matches
764+
)) {
765+
for ($i = 0; $c > $i; $i++) {
766+
$str = str_ireplace(
767+
$matches[0][$i],
768+
'"' . str_rot13($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[3][$i])) . '"',
769+
$str
770+
);
771+
}
772+
continue;
773+
}
774+
if ($c = preg_match_all(
775+
'/(hex2bin\s*\\(\s*["\'])([\da-f]{1,4096})(["\']\s*\\))/i',
776+
$str,
777+
$matches
778+
)) {
779+
for ($i = 0; $c > $i; $i++) {
780+
$str = str_ireplace(
781+
$matches[0][$i],
782+
'"' . $this->Loader->hexSafe($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[3][$i])) . '"',
783+
$str
784+
);
785+
}
786+
continue;
787+
}
788+
if ($c = preg_match_all(
789+
'/([Uu][Nn][Pp][Aa][Cc][Kk]\s*\\(\s*["\']\s*H\*\s*["\']\s*,\s*["\'])([\da-fA-F]{1,4096})(["\']\s*\\))/',
790+
$str,
791+
$matches
792+
)) {
793+
for ($i = 0; $c > $i; $i++) {
794+
$str = str_replace($matches[0][$i], '"' . $this->Loader->hexSafe($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[3][$i])) . '"', $str);
795+
}
796+
continue;
797+
}
798+
break;
799+
}
800+
}
801+
$str = preg_replace('/[^\x21-\x7E]/', '', strtolower($this->prescanDecode($str . $ostr)));
802+
if ($html) {
803+
$str = preg_replace([
804+
'@<script[^>]*?>.*?</script>@si',
805+
'@<[\/\!]*?[^<>]*?>@si',
806+
'@<style[^>]*?>.*?</style>@siU',
807+
'@<![\s\S]*?--[ \t\n\r]*>@'
808+
], '', $str);
809+
}
810+
return trim($str);
811+
}
812+
711813
/**
712814
* Responsible for recursing through any files given to it to be scanned, which
713815
* may be necessary for the case of archives and directories. It performs the
@@ -3301,108 +3403,6 @@ private function memoryUse(string $Path, int $Delete = 0, int $DeleteFiles = 0):
33013403
return $Arr;
33023404
}
33033405

3304-
/**
3305-
* Does some more complex decoding and normalisation work on strings.
3306-
*
3307-
* @param string $str The string to be decoded/normalised.
3308-
* @param bool $html If true, "style" and "script" tags will be stripped from
3309-
* the input string (optional; defaults to false).
3310-
* @param bool $decode If false, the input string will be normalised, but not
3311-
* decoded; If true, the input string will be normalised *and* decoded.
3312-
* Optional; Defaults to false.
3313-
* @return string The decoded/normalised string.
3314-
*/
3315-
private function normalise(string $str, bool $html = false, bool $decode = false): string
3316-
{
3317-
/** Fire event: "atStartOf_normalise". */
3318-
$this->Loader->Events->fireEvent('atStartOf_normalise');
3319-
3320-
$ostr = '';
3321-
if ($decode) {
3322-
$ostr .= $str;
3323-
while (true) {
3324-
if (
3325-
function_exists('gzinflate') &&
3326-
$c = preg_match_all('/(gzinflate\s*\\(\s*["\'])(.{1,4096})(,\d)?(["\']\s*\\))/i', $str, $matches)
3327-
) {
3328-
for ($i = 0; $c > $i; $i++) {
3329-
$str = str_ireplace(
3330-
$matches[0][$i],
3331-
'"' . gzinflate($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[4][$i])) . '"',
3332-
$str
3333-
);
3334-
}
3335-
continue;
3336-
}
3337-
if ($c = preg_match_all(
3338-
'/(base64_decode|decode_base64|base64\.b64decode|atob|Base64\.decode64)(\s*' .
3339-
'\\(\s*["\'\`])([\da-z+\/]{4})*([\da-z+\/]{4}|[\da-z+\/]{3}=|[\da-z+\/]{2}==)(["\'\`]' .
3340-
'\s*\\))/i',
3341-
$str,
3342-
$matches
3343-
)) {
3344-
for ($i = 0; $c > $i; $i++) {
3345-
$str = str_ireplace(
3346-
$matches[0][$i],
3347-
'"' . base64_decode($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i] . $matches[2][$i]), $matches[5][$i])) . '"',
3348-
$str
3349-
);
3350-
}
3351-
continue;
3352-
}
3353-
if ($c = preg_match_all(
3354-
'/(str_rot13\s*\\(\s*["\'])([^\'"\\(\\)]{1,4096})(["\']\s*\\))/i',
3355-
$str,
3356-
$matches
3357-
)) {
3358-
for ($i = 0; $c > $i; $i++) {
3359-
$str = str_ireplace(
3360-
$matches[0][$i],
3361-
'"' . str_rot13($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[3][$i])) . '"',
3362-
$str
3363-
);
3364-
}
3365-
continue;
3366-
}
3367-
if ($c = preg_match_all(
3368-
'/(hex2bin\s*\\(\s*["\'])([\da-f]{1,4096})(["\']\s*\\))/i',
3369-
$str,
3370-
$matches
3371-
)) {
3372-
for ($i = 0; $c > $i; $i++) {
3373-
$str = str_ireplace(
3374-
$matches[0][$i],
3375-
'"' . $this->Loader->hexSafe($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[3][$i])) . '"',
3376-
$str
3377-
);
3378-
}
3379-
continue;
3380-
}
3381-
if ($c = preg_match_all(
3382-
'/([Uu][Nn][Pp][Aa][Cc][Kk]\s*\\(\s*["\']\s*H\*\s*["\']\s*,\s*["\'])([\da-fA-F]{1,4096})(["\']\s*\\))/',
3383-
$str,
3384-
$matches
3385-
)) {
3386-
for ($i = 0; $c > $i; $i++) {
3387-
$str = str_replace($matches[0][$i], '"' . $this->Loader->hexSafe($this->Loader->substrBeforeLast($this->Loader->substrAfterFirst($matches[0][$i], $matches[1][$i]), $matches[3][$i])) . '"', $str);
3388-
}
3389-
continue;
3390-
}
3391-
break;
3392-
}
3393-
}
3394-
$str = preg_replace('/[^\x21-\x7E]/', '', strtolower($this->prescanDecode($str . $ostr)));
3395-
if ($html) {
3396-
$str = preg_replace([
3397-
'@<script[^>]*?>.*?</script>@si',
3398-
'@<[\/\!]*?[^<>]*?>@si',
3399-
'@<style[^>]*?>.*?</style>@siU',
3400-
'@<![\s\S]*?--[ \t\n\r]*>@'
3401-
], '', $str);
3402-
}
3403-
return trim($str);
3404-
}
3405-
34063406
/**
34073407
* Expands phpMussel detection shorthand to complete identifiers, makes some
34083408
* determinations based on those identifiers against the package

0 commit comments

Comments
 (0)