1<?php 2# MantisBT - A PHP based bugtracking system 3 4# MantisBT is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 2 of the License, or 7# (at your option) any later version. 8# 9# MantisBT is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with MantisBT. If not, see <http://www.gnu.org/licenses/>. 16 17/** 18 * GPC API 19 * 20 * Provides sanitisation and type conversion of user supplied data through 21 * HTTP GET, HTTP POST and cookies. 22 * 23 * @package CoreAPI 24 * @subpackage GPCAPI 25 * @copyright Copyright 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 26 * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net 27 * @link http://www.mantisbt.org 28 * 29 * @uses config_api.php 30 * @uses constant_inc.php 31 * @uses error_api.php 32 * @uses http_api.php 33 */ 34 35require_api( 'config_api.php' ); 36require_api( 'constant_inc.php' ); 37require_api( 'error_api.php' ); 38require_api( 'http_api.php' ); 39 40# Determines (once-off) whether the client is accessing this script via a 41# secure connection. If they are, we want to use the Secure cookie flag to 42# prevent the cookie from being transmitted to other domains. 43# @global boolean $g_cookie_secure_flag_enabled 44$g_cookie_secure_flag_enabled = http_is_protocol_https(); 45 46/** 47 * Retrieve a GPC variable. 48 * If the variable is not set, the default is returned. 49 * 50 * You may pass in any variable as a default (including null) but if 51 * you pass in *no* default then an error will be triggered if the field 52 * cannot be found 53 * 54 * @param string $p_var_name Variable name. 55 * @param mixed $p_default Default value. 56 * @return null 57 */ 58function gpc_get( $p_var_name, $p_default = null ) { 59 if( isset( $_POST[$p_var_name] ) ) { 60 $t_result = $_POST[$p_var_name]; 61 } else if( isset( $_GET[$p_var_name] ) ) { 62 $t_result = $_GET[$p_var_name]; 63 } else if( func_num_args() > 1 ) { 64 # check for a default passed in (allowing null) 65 $t_result = $p_default; 66 } else { 67 error_parameters( $p_var_name ); 68 trigger_error( ERROR_GPC_VAR_NOT_FOUND, ERROR ); 69 $t_result = null; 70 } 71 72 return $t_result; 73} 74 75/** 76 * Check if GPC variable is set in $_POST or $_GET 77 * @param string $p_var_name Variable name to check if set by http request. 78 * @return boolean 79 */ 80function gpc_isset( $p_var_name ) { 81 if( isset( $_POST[$p_var_name] ) ) { 82 return true; 83 } else if( isset( $_GET[$p_var_name] ) ) { 84 return true; 85 } 86 87 return false; 88} 89 90/** 91 * Retrieve a string GPC variable. Uses gpc_get(). 92 * If you pass in *no* default, an error will be triggered if 93 * the variable does not exist 94 * @param string $p_var_name Variable name to retrieve. 95 * @param string $p_default Default value of the string if not set(optional). 96 * @return string|null 97 */ 98function gpc_get_string( $p_var_name, $p_default = null ) { 99 # Don't pass along a default unless one was given to us 100 # otherwise we prevent an error being triggered 101 $t_args = func_get_args(); 102 $t_result = call_user_func_array( 'gpc_get', $t_args ); 103 104 if( is_array( $t_result ) ) { 105 error_parameters( $p_var_name ); 106 trigger_error( ERROR_GPC_ARRAY_UNEXPECTED, ERROR ); 107 } 108 109 if( $t_result === null ) { 110 return null; 111 } else { 112 return str_replace( "\0", '', $t_result ); 113 } 114} 115 116/** 117 * Retrieve an integer GPC variable. Uses gpc_get(). 118 * If you pass in *no* default, an error will be triggered if 119 * the variable does not exist 120 * @param string $p_var_name Variable name to retrieve. 121 * @param integer $p_default Default integer value if not set (optional). 122 * @return integer|null 123 */ 124function gpc_get_int( $p_var_name, $p_default = null ) { 125 # Don't pass along a default unless one was given to us 126 # otherwise we prevent an error being triggered 127 $t_args = func_get_args(); 128 $t_result = call_user_func_array( 'gpc_get', $t_args ); 129 130 if( is_array( $t_result ) ) { 131 error_parameters( $p_var_name ); 132 trigger_error( ERROR_GPC_ARRAY_UNEXPECTED, ERROR ); 133 } 134 $t_val = str_replace( ' ', '', trim( $t_result ) ); 135 if( !preg_match( '/^-?([0-9])*$/', $t_val ) ) { 136 error_parameters( $p_var_name ); 137 trigger_error( ERROR_GPC_NOT_NUMBER, ERROR ); 138 } 139 140 return (int)$t_val; 141} 142 143/** 144 * Retrieve a boolean GPC variable. Uses gpc_get(). 145 * If you pass in *no* default, false will be used 146 * @param string $p_var_name Variable name to retrieve. 147 * @param boolean $p_default Default boolean value if not set (optional). 148 * @return boolean|null 149 */ 150function gpc_get_bool( $p_var_name, $p_default = false ) { 151 $t_result = gpc_get( $p_var_name, $p_default ); 152 153 if( $t_result === $p_default ) { 154 return (bool)$p_default; 155 } else { 156 if( is_array( $t_result ) ) { 157 error_parameters( $p_var_name ); 158 trigger_error( ERROR_GPC_ARRAY_UNEXPECTED, ERROR ); 159 } 160 161 return gpc_string_to_bool( $t_result ); 162 } 163} 164 165/** 166 * see if a custom field variable is set. Uses gpc_isset(). 167 * @param string $p_var_name Variable name to retrieve. 168 * @param integer $p_custom_field_type Custom field type. 169 * @return boolean 170 */ 171function gpc_isset_custom_field( $p_var_name, $p_custom_field_type ) { 172 $t_field_name = 'custom_field_' . $p_var_name; 173 174 switch( $p_custom_field_type ) { 175 case CUSTOM_FIELD_TYPE_DATE: 176 # date field is three dropdowns that default to 0 177 # Dropdowns are always present, so check if they are set 178 return gpc_isset( $t_field_name . '_day' ) && 179 gpc_get_int( $t_field_name . '_day', 0 ) != 0 && 180 gpc_isset( $t_field_name . '_month' ) && 181 gpc_get_int( $t_field_name . '_month', 0 ) != 0 && 182 gpc_isset( $t_field_name . '_year' ) && 183 gpc_get_int( $t_field_name . '_year', 0 ) != 0 ; 184 case CUSTOM_FIELD_TYPE_STRING: 185 case CUSTOM_FIELD_TYPE_NUMERIC: 186 case CUSTOM_FIELD_TYPE_FLOAT: 187 case CUSTOM_FIELD_TYPE_ENUM: 188 case CUSTOM_FIELD_TYPE_EMAIL: 189 case CUSTOM_FIELD_TYPE_TEXTAREA: 190 return gpc_isset( $t_field_name ) && !is_blank( gpc_get_string( $t_field_name ) ); 191 default: 192 return gpc_isset( $t_field_name ); 193 } 194} 195 196/** 197 * Retrieve a custom field variable. Uses gpc_get(). 198 * If you pass in *no* default, an error will be triggered if 199 * the variable does not exist 200 * @param string $p_var_name Variable name. 201 * @param integer $p_custom_field_type Custom Field Type. 202 * @param mixed $p_default Default value. 203 * @return string 204 */ 205function gpc_get_custom_field( $p_var_name, $p_custom_field_type, $p_default = null ) { 206 switch( $p_custom_field_type ) { 207 case CUSTOM_FIELD_TYPE_MULTILIST: 208 case CUSTOM_FIELD_TYPE_CHECKBOX: 209 # ensure that the default is an array, if set 210 if( ( $p_default !== null ) && !is_array( $p_default ) ) { 211 $p_default = array( $p_default ); 212 } 213 $t_values = gpc_get_string_array( $p_var_name, $p_default ); 214 if( is_array( $t_values ) ) { 215 return implode( '|', $t_values ); 216 } else { 217 return ''; 218 } 219 break; 220 case CUSTOM_FIELD_TYPE_DATE: 221 $t_day = gpc_get_int( $p_var_name . '_day', 0 ); 222 $t_month = gpc_get_int( $p_var_name . '_month', 0 ); 223 $t_year = gpc_get_int( $p_var_name . '_year', 0 ); 224 if( ( $t_year == 0 ) || ( $t_month == 0 ) || ( $t_day == 0 ) ) { 225 if( $p_default == null ) { 226 return ''; 227 } else { 228 return $p_default; 229 } 230 } else { 231 return strtotime( $t_year . '-' . $t_month . '-' . $t_day ); 232 } 233 break; 234 default: 235 return gpc_get_string( $p_var_name, $p_default ); 236 } 237} 238 239/** 240 * Retrieve a string array GPC variable. Uses gpc_get(). 241 * If you pass in *no* default, an error will be triggered if 242 * the variable does not exist 243 * @param string $p_var_name Variable name to retrieve. 244 * @param array $p_default Default value of the string array if not set. 245 * @return array 246 */ 247function gpc_get_string_array( $p_var_name, array $p_default = null ) { 248 # Don't pass along a default unless one was given to us 249 # otherwise we prevent an error being triggered 250 $t_args = func_get_args(); 251 $t_result = call_user_func_array( 'gpc_get', $t_args ); 252 253 # If the result isn't the default we were given or an array, error 254 if( !((( 1 < func_num_args() ) && ( $t_result === $p_default ) ) || is_array( $t_result ) ) ) { 255 error_parameters( $p_var_name ); 256 trigger_error( ERROR_GPC_ARRAY_EXPECTED, ERROR ); 257 } 258 259 if( !is_array( $t_result ) ) { 260 return $t_result; 261 } 262 $t_array = array(); 263 foreach( $t_result as $t_key => $t_value ) { 264 if( $t_value === null ) { 265 $t_array[$t_key] = null; 266 } else { 267 $t_array[$t_key] = str_replace( "\0", '', $t_value ); 268 } 269 } 270 return $t_array; 271} 272 273/** 274 * Retrieve an integer array GPC variable. Uses gpc_get(). 275 * If you pass in *no* default, an error will be triggered if 276 * the variable does not exist 277 * @param string $p_var_name Variable name to retrieve. 278 * @param array $p_default Default value of the integer array if not set. 279 * @return array 280 */ 281function gpc_get_int_array( $p_var_name, array $p_default = null ) { 282 # Don't pass along a default unless one was given to us 283 # otherwise we prevent an error being triggered 284 $t_args = func_get_args(); 285 $t_result = call_user_func_array( 'gpc_get', $t_args ); 286 287 # If the result isn't the default we were given or an array, error 288 if( !((( 1 < func_num_args() ) && ( $t_result === $p_default ) ) || is_array( $t_result ) ) ) { 289 error_parameters( $p_var_name ); 290 trigger_error( ERROR_GPC_ARRAY_EXPECTED, ERROR ); 291 } 292 if( is_array( $t_result ) ) { 293 foreach( $t_result as $t_key => $t_value ) { 294 $t_result[$t_key] = (int)$t_value; 295 } 296 } 297 298 return $t_result; 299} 300 301/** 302 * Retrieve a boolean array GPC variable. Uses gpc_get(). 303 * If you pass in *no* default, an error will be triggered if the variable does not exist. 304 * @param string $p_var_name Variable name to retrieve. 305 * @param array $p_default Default value of the boolean array if not set. 306 * @return array 307 */ 308function gpc_get_bool_array( $p_var_name, array $p_default = null ) { 309 # Don't pass along a default unless one was given to us 310 # otherwise we prevent an error being triggered 311 $t_args = func_get_args(); 312 $t_result = call_user_func_array( 'gpc_get', $t_args ); 313 314 # If the result isn't the default we were given or an array, error 315 if( !((( 1 < func_num_args() ) && ( $t_result === $p_default ) ) || is_array( $t_result ) ) ) { 316 error_parameters( $p_var_name ); 317 trigger_error( ERROR_GPC_ARRAY_EXPECTED, ERROR ); 318 } 319 320 if( is_array( $t_result ) ) { 321 foreach( $t_result as $t_key => $t_value ) { 322 $t_result[$t_key] = gpc_string_to_bool( $t_value ); 323 } 324 } 325 326 return $t_result; 327} 328 329/** 330 * Retrieve a cookie variable 331 * You may pass in any variable as a default (including null) but if 332 * you pass in *no* default then an error will be triggered if the cookie cannot be found 333 * @param string $p_var_name Variable name to retrieve. 334 * @param string $p_default Default value if not set. 335 * @return string 336 */ 337function gpc_get_cookie( $p_var_name, $p_default = null ) { 338 if( isset( $_COOKIE[$p_var_name] ) ) { 339 $t_result = $_COOKIE[$p_var_name]; 340 } else if( func_num_args() > 1 ) { 341 # check for a default passed in (allowing null) 342 $t_result = $p_default; 343 } else { 344 error_parameters( $p_var_name ); 345 trigger_error( ERROR_GPC_VAR_NOT_FOUND, ERROR ); 346 } 347 348 return $t_result; 349} 350 351/** 352 * Set a cookie variable 353 * If $p_expire is false instead of a number, the cookie will expire when 354 * the browser is closed; if it is true, the default time from the config 355 * file will be used. 356 * If $p_path or $p_domain are omitted, defaults are used. 357 * Set $p_httponly to false if client-side Javascript needs to read/write 358 * the cookie. Otherwise it is safe to leave this value unspecified, as 359 * the default value is true. 360 * @todo this function is to be modified by Victor to add CRC... for now it just passes the parameters through to setcookie() 361 * @param string $p_name Cookie name to set. 362 * @param string $p_value Cookie value to set. 363 * @param boolean|integer $p_expire true: current browser session, false/0: cookie_time_length, otherwise: expiry time. 364 * @param string $p_path Cookie Path - default cookie_path configuration variable. 365 * @param string $p_domain Cookie Domain - default is cookie_domain configuration variable. 366 * @param boolean $p_httponly Default true. 367 * @return boolean - true on success, false on failure 368 */ 369function gpc_set_cookie( $p_name, $p_value, $p_expire = false, $p_path = null, $p_domain = null, $p_httponly = true ) { 370 global $g_cookie_secure_flag_enabled; 371 372 if( false === $p_expire ) { 373 $p_expire = 0; 374 } else if( true === $p_expire ) { 375 $t_cookie_length = config_get_global( 'cookie_time_length' ); 376 $p_expire = time() + $t_cookie_length; 377 } 378 379 if( null === $p_path ) { 380 $p_path = config_get_global( 'cookie_path' ); 381 } 382 383 if( null === $p_domain ) { 384 $p_domain = config_get_global( 'cookie_domain' ); 385 } 386 387 return setcookie( $p_name, $p_value, $p_expire, $p_path, $p_domain, $g_cookie_secure_flag_enabled, true ); 388} 389 390/** 391 * Clear a cookie variable 392 * @param string $p_name Cookie clear to set. 393 * @param string $p_path Cookie path. 394 * @param string $p_domain Cookie domain. 395 * @return boolean 396 */ 397function gpc_clear_cookie( $p_name, $p_path = null, $p_domain = null ) { 398 if( null === $p_path ) { 399 $p_path = config_get_global( 'cookie_path' ); 400 } 401 if( null === $p_domain ) { 402 $p_domain = config_get_global( 'cookie_domain' ); 403 } 404 405 if( isset( $_COOKIE[$p_name] ) ) { 406 unset( $_COOKIE[$p_name] ); 407 } 408 409 # don't try to send cookie if headers are send (guideweb) 410 if( !headers_sent() ) { 411 return setcookie( $p_name, '', -1, $p_path, $p_domain ); 412 } else { 413 return false; 414 } 415} 416 417/** 418 * Retrieve a file variable 419 * You may pass in any variable as a default (including null) but if 420 * you pass in *no* default then an error will be triggered if the file 421 * cannot be found 422 * @param string $p_var_name Variable name. 423 * @param mixed $p_default Default value. 424 * @return mixed 425 */ 426function gpc_get_file( $p_var_name, $p_default = null ) { 427 if( isset( $_FILES[$p_var_name] ) ) { 428 # FILES are not escaped even if magic_quotes is ON, this applies to Windows paths. 429 $t_result = $_FILES[$p_var_name]; 430 } else if( func_num_args() > 1 ) { 431 # check for a default passed in (allowing null) 432 $t_result = $p_default; 433 } else { 434 error_parameters( $p_var_name ); 435 trigger_error( ERROR_GPC_VAR_NOT_FOUND, ERROR ); 436 } 437 438 return $t_result; 439} 440 441/** 442 * Convert a POST/GET parameter to an array if it is not already one. 443 * There is no return value from this function - The $_POST/$_GET are updated as appropriate. 444 * @param string $p_var_name The name of the parameter. 445 * @return void 446 */ 447function gpc_make_array( $p_var_name ) { 448 if( isset( $_POST[$p_var_name] ) && !is_array( $_POST[$p_var_name] ) ) { 449 $_POST[$p_var_name] = array( 450 $_POST[$p_var_name], 451 ); 452 } 453 454 if( isset( $_GET[$p_var_name] ) && !is_array( $_GET[$p_var_name] ) ) { 455 $_GET[$p_var_name] = array( 456 $_GET[$p_var_name], 457 ); 458 } 459} 460 461/** 462 * Convert a string to a bool 463 * @param string $p_string A string to convert to a boolean value. 464 * @return boolean 465 */ 466function gpc_string_to_bool( $p_string ) { 467 $t_value = trim( strtolower( $p_string ) ); 468 switch ( $t_value ) { 469 case 'off': 470 case 'no': 471 case 'n': 472 case 'false': 473 case '0': 474 case '': 475 return false; 476 default: 477 return true; 478 } 479} 480