@@ -13,10 +13,43 @@ final class PhpDocUtil
1313{
1414 /**
1515 * @api
16+ *
17+ * @param CallLike|MethodReflection $callLike
18+ */
19+ public static function matchTaintEscape ($ callLike , Scope $ scope ): ?string
20+ {
21+ if ($ callLike instanceof CallLike) {
22+ $ methodReflection = self ::getMethodReflection ($ callLike , $ scope );
23+ } else {
24+ $ methodReflection = $ callLike ;
25+ }
26+
27+ // XXX does not yet support conditional escaping
28+ // https://psalm.dev/docs/security_analysis/avoiding_false_positives/#conditional-escaping-tainted-input
29+ if (null !== $ methodReflection ) {
30+ // atm no resolved phpdoc for methods
31+ // see https://github.com/phpstan/phpstan/discussions/7657
32+ $ phpDocString = $ methodReflection ->getDocComment ();
33+ if (null !== $ phpDocString && preg_match ('/@psalm-taint-escape\s+(\S+)$/m ' , $ phpDocString , $ matches )) {
34+ return $ matches [1 ];
35+ }
36+ }
37+
38+ return null ;
39+ }
40+
41+ /**
42+ * @param CallLike|MethodReflection $callLike
43+ *
44+ *@api
1645 */
17- public static function commentContains (string $ text , CallLike $ callike , Scope $ scope ): bool
46+ public static function commentContains (string $ text , $ callLike , Scope $ scope ): bool
1847 {
19- $ methodReflection = self ::getMethodReflection ($ callike , $ scope );
48+ if ($ callLike instanceof CallLike) {
49+ $ methodReflection = self ::getMethodReflection ($ callLike , $ scope );
50+ } else {
51+ $ methodReflection = $ callLike ;
52+ }
2053
2154 if (null !== $ methodReflection ) {
2255 // atm no resolved phpdoc for methods
@@ -35,9 +68,9 @@ public static function commentContains(string $text, CallLike $callike, Scope $s
3568 *
3669 * @param string $annotation e.g. '@phpstandba-inference-placeholder'
3770 */
38- public static function matchStringAnnotation (string $ annotation , CallLike $ callike , Scope $ scope ): ?string
71+ public static function matchStringAnnotation (string $ annotation , CallLike $ callLike , Scope $ scope ): ?string
3972 {
40- $ methodReflection = self ::getMethodReflection ($ callike , $ scope );
73+ $ methodReflection = self ::getMethodReflection ($ callLike , $ scope );
4174
4275 if (null !== $ methodReflection ) {
4376 // atm no resolved phpdoc for methods
@@ -57,21 +90,21 @@ public static function matchStringAnnotation(string $annotation, CallLike $calli
5790 return null ;
5891 }
5992
60- private static function getMethodReflection (CallLike $ callike , Scope $ scope ): ?MethodReflection
93+ private static function getMethodReflection (CallLike $ callLike , Scope $ scope ): ?MethodReflection
6194 {
6295 $ methodReflection = null ;
63- if ($ callike instanceof Expr \StaticCall) {
64- if ($ callike ->class instanceof Name && $ callike ->name instanceof Identifier) {
65- $ classType = $ scope ->resolveTypeByName ($ callike ->class );
66- $ methodReflection = $ scope ->getMethodReflection ($ classType , $ callike ->name ->name );
96+ if ($ callLike instanceof Expr \StaticCall) {
97+ if ($ callLike ->class instanceof Name && $ callLike ->name instanceof Identifier) {
98+ $ classType = $ scope ->resolveTypeByName ($ callLike ->class );
99+ $ methodReflection = $ scope ->getMethodReflection ($ classType , $ callLike ->name ->name );
67100 }
68- } elseif ($ callike instanceof Expr \MethodCall && $ callike ->name instanceof Identifier) {
101+ } elseif ($ callLike instanceof Expr \MethodCall && $ callLike ->name instanceof Identifier) {
69102 $ classReflection = $ scope ->getClassReflection ();
70- if (null !== $ classReflection && $ classReflection ->hasMethod ($ callike ->name ->name )) {
71- $ methodReflection = $ classReflection ->getMethod ($ callike ->name ->name , $ scope );
103+ if (null !== $ classReflection && $ classReflection ->hasMethod ($ callLike ->name ->name )) {
104+ $ methodReflection = $ classReflection ->getMethod ($ callLike ->name ->name , $ scope );
72105 } else {
73- $ callerType = $ scope ->getType ($ callike ->var );
74- $ methodReflection = $ scope ->getMethodReflection ($ callerType , $ callike ->name ->name );
106+ $ callerType = $ scope ->getType ($ callLike ->var );
107+ $ methodReflection = $ scope ->getMethodReflection ($ callerType , $ callLike ->name ->name );
75108 }
76109 }
77110
0 commit comments