brightnucleus /
namespace-backtracer
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Bright Nucleus Namespace Backtracer. |
||
| 4 | * |
||
| 5 | * Get the namespace of the calling object. |
||
| 6 | * |
||
| 7 | * @package BrightNucleus\NamespaceBacktracer |
||
| 8 | * @author Alain Schlesser <[email protected]> |
||
| 9 | * @license MIT |
||
| 10 | * @link https://www.brightnucleus.com/ |
||
| 11 | * @copyright 2016 Alain Schlesser, Bright Nucleus |
||
| 12 | */ |
||
| 13 | |||
| 14 | namespace BrightNucleus\NamespaceBacktracer; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Trait NamespaceBacktracerTrait. |
||
| 18 | * |
||
| 19 | * @since 0.1.0 |
||
| 20 | * |
||
| 21 | * @author Alain Schlesser <[email protected]> |
||
| 22 | */ |
||
| 23 | trait NamespaceBacktracerTrait |
||
| 24 | { |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Get the caller from debug_backtrace() info. |
||
| 28 | * |
||
| 29 | * This traverses the call stack until it finds the first function that is |
||
| 30 | * not a method of an ignored class/interface. |
||
| 31 | * You should pass in the output of |
||
| 32 | * `debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)`. |
||
| 33 | * |
||
| 34 | * @since 0.1.0 |
||
| 35 | * |
||
| 36 | * @param array|null $debugInfo Optional. Output of `debug_backtrace()` function. |
||
| 37 | * |
||
| 38 | * @return string Fully qualified name of the calling object/function. |
||
| 39 | */ |
||
| 40 | 8 | protected function getCaller($debugInfo = null) |
|
| 41 | { |
||
| 42 | // Fetch the debugInfo if none was passed in. |
||
| 43 | 8 | if ($debugInfo === null) { |
|
| 44 | 3 | $debugInfo = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); |
|
| 45 | } |
||
| 46 | |||
| 47 | 8 | $ignoredInterfaces = $this->getIgnoredInterfaces(); |
|
| 48 | 8 | $ignoredFunctions = $this->getIgnoredFunctions(); |
|
| 49 | |||
| 50 | 8 | foreach ($debugInfo as $entry) { |
|
| 51 | 8 | $found = false; |
|
| 52 | |||
| 53 | // Are we dealing with a class method or a function? |
||
| 54 | 8 | if (isset($entry['class']) && ! empty($entry['class'])) { |
|
| 55 | 8 | $class = $entry['class']; |
|
| 56 | |||
| 57 | 8 | $ignored = false; |
|
| 58 | 8 | foreach ($ignoredInterfaces as $ignoredInterface) { |
|
| 59 | 4 | if ($class === $ignoredInterface) { |
|
| 60 | 4 | $ignored = true; |
|
| 61 | 4 | break; |
|
| 62 | } |
||
| 63 | 4 | if (is_subclass_of($class, $ignoredInterface)) { |
|
| 64 | $ignored = true; |
||
| 65 | 4 | break; |
|
| 66 | } |
||
| 67 | } |
||
| 68 | 8 | if (! $ignored) { |
|
| 69 | 8 | $found = $class; |
|
| 70 | } |
||
| 71 | } else { |
||
| 72 | $function = $entry['function']; |
||
| 73 | if (! in_array($function, $ignoredFunctions, true)) { |
||
| 74 | $found = $function; |
||
| 75 | } |
||
| 76 | } |
||
| 77 | |||
| 78 | 8 | if (false !== $found) { |
|
| 79 | 8 | return $found; |
|
| 80 | } |
||
| 81 | } |
||
| 82 | |||
| 83 | return ''; |
||
| 84 | } |
||
| 85 | |||
| 86 | /** |
||
| 87 | * Get the caller's namespace from debug_backtrace() info. |
||
| 88 | * |
||
| 89 | * This traverses the call stack until it finds the first function that is |
||
| 90 | * not a method of an ignored class/interface. |
||
| 91 | * You should pass in the output of |
||
| 92 | * `debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)`. |
||
| 93 | * |
||
| 94 | * @since 0.1.0 |
||
| 95 | * |
||
| 96 | * @param array|null $debugInfo Optional. Output of `debug_backtrace()` function. |
||
| 97 | * |
||
| 98 | * @return string Namespace of the calling object. |
||
| 99 | */ |
||
| 100 | 4 | protected function getCallingNamespace($debugInfo = null) |
|
| 101 | { |
||
| 102 | // Fetch the debugInfo if none was passed in. |
||
| 103 | 4 | if ($debugInfo === null) { |
|
| 104 | 3 | $debugInfo = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); |
|
| 105 | } |
||
| 106 | |||
| 107 | 4 | $namespace = $this->extractNamespace($this->getCaller($debugInfo)); |
|
| 108 | |||
| 109 | 4 | return '' !== $namespace |
|
| 110 | 2 | ? $namespace |
|
| 111 | 4 | : $this->getGlobalNamespace(); |
|
| 112 | } |
||
| 113 | |||
| 114 | /** |
||
| 115 | * Extract the namespace from a fully qualified class name. |
||
| 116 | * |
||
| 117 | * @since 0.1.0 |
||
| 118 | * |
||
| 119 | * @param string $class Fully qualified class name. |
||
| 120 | * |
||
| 121 | * @return string Namespace of the class. Empty string if none. |
||
| 122 | */ |
||
| 123 | 4 | protected function extractNamespace($class) |
|
| 124 | { |
||
| 125 | 4 | $pos = strrpos($class, '\\'); |
|
| 126 | 4 | if (false === $pos) { |
|
| 127 | 2 | return ''; |
|
| 128 | } |
||
| 129 | |||
| 130 | 2 | return substr($class, 0, $pos); |
|
| 131 | } |
||
| 132 | |||
| 133 | /** |
||
| 134 | * Get an array of interfaces/classes to ignore while fetching a namespace. |
||
| 135 | * |
||
| 136 | * Override this method to adapt the output to your specific environment. |
||
| 137 | * |
||
| 138 | * @since 0.1.0 |
||
| 139 | * |
||
| 140 | * @return array Array of interface/class names. |
||
| 141 | */ |
||
| 142 | protected function getIgnoredInterfaces() |
||
| 143 | { |
||
| 144 | return []; |
||
| 145 | } |
||
| 146 | |||
| 147 | /** |
||
| 148 | * Get an array of functions to ignore while fetching a namespace. |
||
| 149 | * |
||
| 150 | * Override this method to adapt the output to your specific environment. |
||
| 151 | * |
||
| 152 | * @since 0.1.0 |
||
| 153 | * |
||
| 154 | * @return array Array of function names. |
||
|
0 ignored issues
–
show
|
|||
| 155 | */ |
||
| 156 | protected function getIgnoredFunctions() |
||
| 157 | { |
||
| 158 | return [ |
||
| 159 | 'call_user_func', |
||
| 160 | ]; |
||
| 161 | } |
||
| 162 | |||
| 163 | /** |
||
| 164 | * Get the string that is returned when the global namespace was hit. |
||
| 165 | * |
||
| 166 | * Override this method to adapt the output to your specific environment. |
||
| 167 | * |
||
| 168 | * @since 0.1.0 |
||
| 169 | * |
||
| 170 | * @return string String that represents the global namespace. |
||
| 171 | */ |
||
| 172 | protected function getGlobalNamespace() |
||
| 173 | { |
||
| 174 | return '(global)'; |
||
| 175 | } |
||
| 176 | } |
||
| 177 |
This check looks for the generic type
arrayas a return type and suggests a more specific type. This type is inferred from the actual code.