/wp-content/plugins/jetpack/vendor/automattic/jetpack-waf/src/class-waf-operators.php

https://gitlab.com/remyvianne/krowkaramel · PHP · 286 lines · 121 code · 25 blank · 140 comment · 18 complexity · 087880ce56e8b1928638eca6ecd04198 MD5 · raw file

  1. <?php
  2. /**
  3. * Rule compiler for Jetpack Waf.
  4. *
  5. * @package automattic/jetpack-waf
  6. */
  7. namespace Automattic\Jetpack\Waf;
  8. /**
  9. * WafOperators class
  10. */
  11. class WafOperators {
  12. /**
  13. * Returns true if the test string is found at the beginning of the input.
  14. *
  15. * @param string $input Input.
  16. * @param string $test Test.
  17. * @return string|false
  18. */
  19. public function begins_with( $input, $test ) {
  20. if ( '' === $input && '' === $test ) {
  21. return '';
  22. }
  23. return substr( $input, 0, strlen( $test ) ) === $test
  24. ? $test
  25. : false;
  26. }
  27. /**
  28. * Returns true if the test string is found anywhere in the input.
  29. *
  30. * @param string $input Input.
  31. * @param string $test Test.
  32. * @return string|false
  33. */
  34. public function contains( $input, $test ) {
  35. if ( empty( $input ) || empty( $test ) ) {
  36. return false;
  37. }
  38. return strpos( $input, $test ) !== false
  39. ? $test
  40. : false;
  41. }
  42. /**
  43. * Returns true if the test string with word boundaries is found anywhere in the input.
  44. *
  45. * @param string $input Input.
  46. * @param string $test Test.
  47. * @return string|false
  48. */
  49. public function contains_word( $input, $test ) {
  50. return ( $input === $test || 1 === preg_match( '/\b' . preg_quote( $test, '/' ) . '\b/Ds', $input ) )
  51. ? $test
  52. : false;
  53. }
  54. /**
  55. * Returns true if the test string is found at the end of the input.
  56. *
  57. * @param string $input Input.
  58. * @param string $test Test.
  59. * @return string|false
  60. */
  61. public function ends_with( $input, $test ) {
  62. return ( '' === $test || substr( $input, -1 * strlen( $test ) ) === $test )
  63. ? $test
  64. : false;
  65. }
  66. /**
  67. * Returns true if the input value is equal to the test value.
  68. * If either value cannot be converted to an int it will be treated as 0.
  69. *
  70. * @param mixed $input Input.
  71. * @param mixed $test Test.
  72. * @return int|false
  73. */
  74. public function eq( $input, $test ) {
  75. return intval( $input ) === intval( $test )
  76. ? $input
  77. : false;
  78. }
  79. /**
  80. * Returns true if the input value is greater than or equal to the test value.
  81. * If either value cannot be converted to an int it will be treated as 0.
  82. *
  83. * @param mixed $input Input.
  84. * @param mixed $test Test.
  85. * @return int|false
  86. */
  87. public function ge( $input, $test ) {
  88. return intval( $input ) >= intval( $test )
  89. ? $input
  90. : false;
  91. }
  92. /**
  93. * Returns true if the input value is greater than the test value.
  94. * If either value cannot be converted to an int it will be treated as 0.
  95. *
  96. * @param mixed $input Input.
  97. * @param mixed $test Test.
  98. * @return int|false
  99. */
  100. public function gt( $input, $test ) {
  101. return intval( $input ) > intval( $test )
  102. ? $input
  103. : false;
  104. }
  105. /**
  106. * Returns true if the input value is less than or equal to the test value.
  107. * If either value cannot be converted to an int it will be treated as 0.
  108. *
  109. * @param mixed $input Input.
  110. * @param mixed $test Test.
  111. * @return int|false
  112. */
  113. public function le( $input, $test ) {
  114. return intval( $input ) <= intval( $test )
  115. ? $input
  116. : false;
  117. }
  118. /**
  119. * Returns true if the input value is less than the test value.
  120. * If either value cannot be converted to an int it will be treated as 0.
  121. *
  122. * @param mixed $input Input.
  123. * @param mixed $test Test.
  124. * @return int|false
  125. */
  126. public function lt( $input, $test ) {
  127. return intval( $input ) < intval( $test )
  128. ? $input
  129. : false;
  130. }
  131. /**
  132. * Returns false.
  133. *
  134. * @return false
  135. */
  136. public function no_match() {
  137. return false;
  138. }
  139. /**
  140. * Uses a multi-string matching algorithm to search through $input for a number of given $words.
  141. *
  142. * @param string $input Input.
  143. * @param string[] $words \AhoCorasick\MultiStringMatcher $matcher.
  144. * @return string[]|false Returns the words that were found in $input, or FALSE if no words were found.
  145. */
  146. public function pm( $input, $words ) {
  147. $results = $this->get_multi_string_matcher( $words )->searchIn( $input );
  148. return isset( $results[0] )
  149. ? array_map(
  150. function ( $r ) {
  151. return $r[1]; },
  152. $results
  153. )
  154. : false;
  155. }
  156. /**
  157. * The last-used pattern-matching algorithm.
  158. *
  159. * @var array
  160. */
  161. private $last_multi_string_matcher = array( null, null );
  162. /**
  163. * Creates a matcher that uses the Aho-Corasick algorithm to efficiently find a number of words in an input string.
  164. * Caches the last-used matcher so that the same word list doesn't have to be compiled multiple times.
  165. *
  166. * @param string[] $words Words.
  167. * @return \AhoCorasick\MultiStringMatcher
  168. */
  169. private function get_multi_string_matcher( $words ) {
  170. // only create a new matcher entity if we don't have one already for this word list.
  171. if ( $this->last_multi_string_matcher[0] !== $words ) {
  172. $this->last_multi_string_matcher = array( $words, new \AhoCorasick\MultiStringMatcher( $words ) );
  173. }
  174. return $this->last_multi_string_matcher[1];
  175. }
  176. /**
  177. * Performs a regular expression match on the input subject using the given pattern.
  178. * Returns false if the pattern does not match, or the substring(s) of the input
  179. * that were matched by the pattern.
  180. *
  181. * @param string $subject Subject.
  182. * @param string $pattern Pattern.
  183. * @return string[]|false
  184. */
  185. public function rx( $subject, $pattern ) {
  186. $matched = preg_match( $pattern, $subject, $matches );
  187. return 1 === $matched
  188. ? $matches
  189. : false;
  190. }
  191. /**
  192. * Returns true if the given input string matches the test string.
  193. *
  194. * @param string $input Input.
  195. * @param string $test Test.
  196. * @return string|false
  197. */
  198. public function streq( $input, $test ) {
  199. return $input === $test
  200. ? $test
  201. : false;
  202. }
  203. /**
  204. * Returns true.
  205. *
  206. * @param string $input Input.
  207. * @return bool
  208. */
  209. public function unconditional_match( $input ) {
  210. return $input;
  211. }
  212. /**
  213. * Checks to see if the input string only contains characters within the given byte range
  214. *
  215. * @param string $input Input.
  216. * @param array $valid_range Valid range.
  217. * @return string
  218. */
  219. public function validate_byte_range( $input, $valid_range ) {
  220. if ( '' === $input ) {
  221. // an empty string is considered "valid".
  222. return false;
  223. }
  224. $i = 0;
  225. while ( isset( $input[ $i ] ) ) {
  226. $n = ord( $input[ $i ] );
  227. if ( $n < $valid_range['min'] || $n > $valid_range['max'] ) {
  228. return $input[ $i ];
  229. }
  230. $valid = false;
  231. foreach ( $valid_range['range'] as $b ) {
  232. if ( $n === $b || is_array( $b ) && $n >= $b[0] && $n <= $b[1] ) {
  233. $valid = true;
  234. break;
  235. }
  236. }
  237. if ( ! $valid ) {
  238. return $input[ $i ];
  239. }
  240. $i++;
  241. }
  242. // if there weren't any invalid bytes, return false.
  243. return false;
  244. }
  245. /**
  246. * Returns true if the input value is found anywhere inside the test value
  247. * (i.e. the inverse of @contains)
  248. *
  249. * @param mixed $input Input.
  250. * @param mixed $test Test.
  251. * @return string|false
  252. */
  253. public function within( $input, $test ) {
  254. if ( '' === $input || '' === $test ) {
  255. return false;
  256. }
  257. return stripos( $test, $input ) !== false
  258. ? $input
  259. : false;
  260. }
  261. }