Completed
Push — master ( 2fd43b...5c5b3d )
by Lars
01:28
created

ValidatorHelpers::getArgsFromString()   C

Complexity

Conditions 7
Paths 3

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7.0671

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 16
cts 18
cp 0.8889
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 19
nc 3
nop 1
crap 7.0671
1
<?php
2
3
declare(strict_types=1);
4
5
namespace voku\HtmlFormValidator;
6
7
use voku\helper\UTF8;
8
9
/**
10
 * Class ValidatorHelpers
11
 *
12
 * @internal
13
 */
14
class ValidatorHelpers
15
{
16
  /**
17
   * @param string $string
18
   *
19
   * @return array
20
   */
21 18
  public static function getArgsFromString($string): array
22
  {
23 18
    $argsMatches = [];
24 18
    \preg_match('/\((?<args>.*?)\)$/', $string, $argsMatches);
25 18
    $string = (string)\preg_replace('/\((.*?)\)$/', '', $string);
26
27 18
    $args = [];
28 18
    if (isset($argsMatches['args'])) {
29 10
      $argTmpString = $argsMatches['args'];
30
31 10
      if (self::is_serialized($argTmpString, $argsTmpUnserialized)) {
32
33 3
        $args = [$argsTmpUnserialized];
34
35
      } else {
36
37 8
        $argsTmpArray = explode(',', $argTmpString);
38 8
        foreach ($argsTmpArray as $argTmp) {
39 8
          $arg = trim($argTmp);
40
41 8
          if ($arg === 'true' || $arg === 'false') {
42
            $arg = (bool)$arg;
43 8
          } else if ($args === 'null') {
44
            $arg = null;
45
          }
46
47 8
          $args[] = $arg;
48
        }
49
50
      }
51
    }
52
53 18
    return [$string, $args];
54
  }
55
56
  /**
57
   * Tests if an input is valid PHP serialized string.
58
   *
59
   * Checks if a string is serialized using quick string manipulation
60
   * to throw out obviously incorrect strings. Unserialize is then run
61
   * on the string to perform the final verification.
62
   *
63
   * Valid serialized forms are the following:
64
   * <ul>
65
   * <li>boolean: <code>b:1;</code></li>
66
   * <li>integer: <code>i:1;</code></li>
67
   * <li>double: <code>d:0.2;</code></li>
68
   * <li>string: <code>s:4:"test";</code></li>
69
   * <li>array: <code>a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}</code></li>
70
   * <li>object: <code>O:8:"stdClass":0:{}</code></li>
71
   * <li>null: <code>N;</code></li>
72
   * </ul>
73
   *
74
   * @author     Chris Smith <[email protected]>
75
   * @copyright  Copyright (c) 2009 Chris Smith (http://www.cs278.org/)
76
   * @license    http://sam.zoy.org/wtfpl/ WTFPL
77
   *
78
   * @param    string $value  Value to test for serialized form
79
   * @param    mixed  $result Result of unserialize() of the $value
80
   *
81
   * @return    boolean      True if $value is serialized data, otherwise false
82
   */
83 10
  public static function is_serialized($value, &$result = null): bool
84
  {
85
    // Bit of a give away this one
86 10
    if (!\is_string($value)) {
87
      return false;
88
    }
89
90
    // Serialized false, return true. unserialize() returns false on an
91
    // invalid string or it could return false if the string is serialized
92
    // false, eliminate that possibility.
93 10
    if ($value === 'b:0;') {
94
      $result = false;
95
96
      return true;
97
    }
98
99 10
    $length = UTF8::strlen($value);
100 10
    $end = '';
101 10
    switch ($value[0]) {
102 10
      case 's':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
103
        if ($value[$length - 2] !== '"') {
104
          return false;
105
        }
106 10
      case 'b':
107 10
      case 'i':
108 10
      case 'd':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
109
        // This looks odd but it is quicker than isset()ing
110
        $end .= ';';
111 10
      case 'a':
112 8
      case 'O':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
113 3
        $end .= '}';
114 3
        if ($value[1] !== ':') {
115
          return false;
116
        }
117 3
        switch ($value[2]) {
118 3
          case 0:
119 3
          case 1:
120 3
          case 2:
121 3
          case 3:
122 1
          case 4:
123 1
          case 5:
124
          case 6:
125
          case 7:
126
          case 8:
127
          case 9:
128 3
            break;
129
          default:
130
            return false;
131
        }
132 8
      case 'N':
133 3
        $end .= ';';
134 3
        if ($value[$length - 1] !== $end[0]) {
135
          return false;
136
        }
137 3
        break;
138
      default:
139 8
        return false;
140
    }
141
142
    /** @noinspection PhpUsageOfSilenceOperatorInspection */
143 3
    if (($result = @unserialize($value, [])) === false) {
144
      $result = null;
145
146
      return false;
147
    }
148
149 3
    return true;
150
  }
151
}
152