public
Description: A lightweight MVC framework on top of Grok-PHP
Homepage: http://chippino.googlecode.com
Clone URL: git://github.com/Jakobo/chippino.git
commit  d3a79fdb286807a98533ba4eb4e7eff7ca9cfe7f
tree    7c6b63bb63bc9b7e97e345e1be19a82d040b9f0a
parent  cb83fceff9a2a9c0fe1c1545735896384ea84800
chippino / library / chippino / util / request / sanitize.php
100644 141 lines (115 sloc) 4.813 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
 
/**
* Sanitizes an element based on the provided type
* @param $value what to sanitize
* @param $as what to sanitize the value as
* @return mixed
**/
 
$as = strtolower($this->as);
$value = $this->value;
 
// universal cleaning
if (get_magic_quotes_gpc()) {
  $value = stripslashes($value);
}
 
// standardize newlines if needed
if (strpos($value, "\r") !== FALSE) {
  $value = str_replace(array("\r\n", "\r"), "\n", $value);
}
 
// standardize spaces if needed
if (strpos($value, "\t") !== FALSE) {
  $value = str_replace(array("\t"), " ", $value);
}
 
switch ($as) {
    case 'raw':
        return $value;
        
    case 'string':
        $value = str_replace(array("\r\n", "\r"), "\n", $value);
        
    $value = preg_replace('/\0+/', '', $value);
    $value = preg_replace('/(\\\\0)+/', '', $value);
    
        return chip('Chippino/Util/Request/_XSS')->with(array(
            'value' => $value,
        ));
    
    case 'float':
        $is_negative = (strpos($value, '-') === 0) ? TRUE : FALSE;
        $value = trim($value, '-');
    
        // get the fractional part of the number and convert it to a floatval
        // friendly usable part
        if (strpos($value, '.') !== FALSE) {
            $f_part = preg_replace('/(.*?)[^0-9]([0-9]+).*$/iu', '\2', $value);
            $f_part = preg_replace('/[^0-9]/iu', '', $f_part);
        }
        else {
            $f_part = 0;
        }
        
        // capture the interger part
        // see getAsInt preg
        $value = preg_replace('/([0-9]+)(.*)$/iu', '\1', $value);
        $value = preg_replace('/[^0-9]/iu', '', $value);
        
        // we can use the significant bit calc here, but for now, just return the
        // proper floatval of the safer number
        return ($is_negative) ? -1 * floatval($value.'.'.$f_part) : floatval($value.'.'.$f_part);
 
    case 'int':
        // setups
        $has_bc_math = (function_exists('bccomp')) ? TRUE : FALSE;
        $has_bc_math = (chipi('Chippino/Util/Config')->with()->core['force_bc_math'] !== NULL) ? chipi('Chippino/Util/Config')->with()->core['force_bc_math'] : $has_bc_math;
 
        if (chipi('Chippino/Util/Config')->with()->core['max_bit_size'] != 64) {
           $max_int = '2147483647';
           $min_int = '-2147483648';
        }
        else {
            $max_int = '9223372036854775807';
            $min_int = '-9223372036854775808';
        }
        
        // detect negative and trim
        $is_negative = (strpos($value, '-') === 0) ? TRUE : FALSE;
        $value = trim($value, '-');
        
        // consider the last non-numeric a decimal place, and truncate
        // this is a cheap way of reducing the dependancy on i18n
        // we can then consider what's left to be the interger part and strip
        // all non numerics
        $value = preg_replace('/(.*)([^0-9][0-9]*?)$/iu', '\1', $value);
        $value = preg_replace('/[^0-9]/iu', '', $value);
        
        // if there is nothing left, then there was no int provided
        if (strlen($value) === 0) {
            return 0;
        }
        
        // if the incoming string is shorter than our max size, we can
        // safely intval it. (#7)
        if (strlen($value) < strlen($max_int)) {
            return ($is_negative) ? -1 * intval($value) : intval($value);
        }
        
        // if it's longer than maxint, we also know it is no good
        if (strlen($value) > strlen($max_int)) {
            return 0;
        }
        
        // return with intval if we can't do a proper comparisson
        // using bcmath. We'd really prefer BCMATH if it's loaded.
        if (!$has_bc_math) {
            // compare each item to 2147483647 left to right
            // zero pad value as a string
            $compare = str_split($max_int);
            $value_compare = str_split(str_pad($value, strlen($max_int), '0', STR_PAD_LEFT));
 
            $prev_place = FALSE;
            foreach ($value_compare as $idx => $place) {
                if ($place > $compare[$idx]) {
                    if ($prev_place >= $compare[$idx-1]) {
                        // overflow reached
                        return 0;
                    }
                    $prev_place = $place;
                }
                else {
                    // in the clear
                    $prev_place = FALSE;
                }
            }
            return ($is_negative) ? -1 * intval($value) : intval($value);
        }
        
        // do bcmath to protect the value as an int
        if (bccomp($value, $max_int) > 0) return 0;
        if (bccomp($value, $min_int) < 0) return 0;
        
        // all that's left is something that should come back an INT
        return ($is_negative) ? -1 * intval($value) : intval($value);
 
  default:
    return NULL;
}