Issues (1752)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/cache/cache.php (16 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
require_once(dirname(__FILE__) . '/../fwolflib.php');
3
require_once(dirname(__FILE__) . '/../../func/array.php');
4
require_once(dirname(__FILE__) . '/../../func/string.php');
5
6
7
/**
8
 * Parent class for Key - value cache system
9
 *
10
 * Data store in various way, define in sub class, call use Create().
11
 * As factory This class is also subclass creator, so not abstract.
12
 *
13
 * Main method:
14
 * -	Key(), hash or use original key.
15
 * -	Set(), write cache data
16
 * -	Get(), read cache data
17
 * -	Del(), delete cache data
18
 *
19
 * @deprecated  Use Fwlib\Cache\Cache
20
 * @package		fwolflib
21
 * @subpackage	class.cache
22
 * @copyright	Copyright 2012, Fwolf
23
 * @author		Fwolf <[email protected]>
24
 * @since		2012-09-14
25
 */
26
class Cache extends Fwolflib {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The type Cache has been defined more than once; this definition is ignored, only the first definition in class/cache.php (L35-376) is considered.

This check looks for classes that have been defined more than once.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
Deprecated Code introduced by
The class Fwolflib has been deprecated with message: Use classes in Fwlib namespace, see PSR-0/1/2

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
27
28
	/**
29
	 * Cache data for cache type ''
30
	 *
31
	 * @var	array
32
	 */
33
	protected $aCache = array();
34
35
	/**
36
	 * Log for Get op's key and success flag
37
	 *
38
	 * array(
39
	 * 	array(
40
	 * 		key: string,
41
	 * 		success: boolean,
42
	 * 	)
43
	 * )
44
	 *
45
	 * @var	array
46
	 */
47
	public static $aLogGet = array();
48
49
50
	/**
51
	 * Constructor
52
	 *
53
	 * @param	array	$ar_cfg
54
	 */
55
	public function __construct ($ar_cfg = array()) {
56
		parent::__construct($ar_cfg);
57
58
		// Unset for auto new
59
	} // end of func __construct
60
61
62
	/**
63
	 * Factory create method
64
	 *
65
	 * @param	string	$type			Cache type
66
	 * @param	array	$ar_cfg
67
	 * @return	object
68
	 */
69
	public static function Create ($type = '', $ar_cfg = array()) {
70
		// Supported cache type
71
		if (!in_array($type, array('',
72
			'file',
73
			'memcached',
74
			))) {
75
			// $this is not allowed in static func
76
			//$this->Log('Cache type ' . $type . ' not supported.', 4);
77
			error_log('Cache type ' . $type . ' not supported.');
78
			return NULL;
79
		}
80
81
82
		// Include file, new obj
83
		$s_filename = 'cache'
84
			. (empty($type) ? '' : '-') . $type;
85
		$s_classname = StrUnderline2Ucfirst($s_filename, true);
0 ignored issues
show
Deprecated Code introduced by
The function StrUnderline2Ucfirst() has been deprecated with message: Use Fwlib\Util\StringUtil::toStudlyCaps()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
86
		$s_filename .= '.php';
87
88
		require_once(dirname(__FILE__) . '/' . $s_filename);
89
		return (new $s_classname($ar_cfg));
90
	} // end of func Create
91
92
93
	/**
94
	 * Del cache data
95
	 *
96
	 * @param	string	$key
97
	 * @return	$this
98
	 */
99
	public function Del ($key) {
100
		unset($this->aCache[$key]);
101
		return $this;
102
	} // end of func Del
103
104
105
	/**
106
	 * Is cache data expire ?
107
	 *
108
	 * @param	string	$key
109
	 * @return	boolean
110
	 */
111
	public function Expire ($key) {
112
		// Inner var never expire,
113
		// Also, there is no good method to keep var set time.
114
		return false;
115
	} // end of func Expire
116
117
118
	/**
119
	 * Compute expiration time
120
	 *
121
	 * @param	int		$lifetime
122
	 * @param	int		$t_base			Base start time, 0 use time().
123
	 * @return	int						In unix time.
124
	 */
125
	public function ExpireTime ($lifetime = NULL, $t_base = 0) {
126
		// If not set, use config
127
		if (is_null($lifetime))
128
			$lifetime = $this->aCfg['cache-lifetime'];
129
130
		// 0 means never expire
131
		if (0 == $lifetime)
132
			return 0;
133
134
		if (0 == $t_base)
135
			$t_base = time();
136
137
		// If smaller than 30days
138
		if (2592000 >= $lifetime) {
139
			return $t_base + $lifetime;
140
		}
141
142
		// Larger than 30days, it's unix timestamp, ignore $t_base
143
		return $lifetime;
144
	} // end of func ExpireTime
145
146
147
	/**
148
	 * Load cache data
149
	 *
150
	 * @param	string	$key
151
	 * @param	int		$lifetime		Cache lifetime
152
	 * @return	mixed
153
	 */
154
	public function Get ($key, $lifetime = NULL) {
155
		$key = $this->Key($key);
0 ignored issues
show
It seems like you code against a specific sub-type and not the parent class Cache as the method Key() does only exist in the following sub-classes of Cache: CacheMemcached. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
156
157
		// Ignored lifetime
158
		$val = $this->ValDecode(
0 ignored issues
show
The method ValDecode() does not seem to exist on object<Cache>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
159
			ArrayRead($this->aCache, $key, NULL)
0 ignored issues
show
The property aCache does not exist on object<Cache>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Deprecated Code introduced by
The function ArrayRead() has been deprecated with message: Use Fwlib\Util\ArrayUtil::getIdx(), getEdx()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
160
			, 0);
161
162
		self::$aLogGet[] = array(
163
			'key'	=> $key,
164
			'success'	=> !is_null($val),
165
		);
166
		return $val;
167
	} // end of func Get
168
169
170
	/**
171
	 * Gen cache key
172
	 *
173
	 * In some cache system, key may need hash or computed.
174
	 *
175
	 * @param	string	$str
176
	 * @return	string
177
	 */
178
	public function Key ($str) {
179
		return $str;
180
	} // end of func Key
181
182
183
	/**
184
	 * Write data to cache
185
	 *
186
	 * @param	string	$key
187
	 * @param	mixed	$val
188
	 * @param	int		$lifetime
189
	 * @return	$this
190
	 */
191
	public function Set ($key, $val, $lifetime = NULL) {
192
		// Lifetime is useless.
193
		$this->aCache[$this->Key($key)] = $this->ValEncode($val, 0);
0 ignored issues
show
The property aCache does not exist on object<Cache>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
It seems like you code against a specific sub-type and not the parent class Cache as the method Key() does only exist in the following sub-classes of Cache: CacheMemcached. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
The method ValEncode() does not seem to exist on object<Cache>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
194
		return $this;
195
	} // end of func Set
196
197
198
	/**
199
	 * Set default config
200
	 *
201
	 * @return	this
202
	 */
203 View Code Duplication
	protected function SetCfgDefault () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
		parent::SetCfgDefault();
205
206
		// Cache type: file, memcached
207
		// Empty means parent cache class.
208
		$this->aCfg['cache-type'] = '';
209
210
		// Cache store method
211
		// 0: Raw string or other value.
212
		//	User should determine the value DO suite cache type.
213
		// 1: Json, decode to array.
214
		// 2: Json, decode to object.
215
		$this->aCfg['cache-store-method'] = 1;
216
217
		// Default cache lifetime, in second
218
		// Can be overwrite by param when get/set.
219
		// Default/Max 30days:
220
		//   60sec * 60min = 3600s * 24h = 86400s * 30 = 2592000s
221
		// Larger than 30days, must assign unix time like memcached,
222
		//   which is number of seconds since 1970-1-1 as an integer.
223
		// 0 means forever.
224
		$this->aCfg['cache-lifetime'] = 2592000;
225
226
		return $this;
227
	} // end of func SetCfgDefault
228
229
230
	/**
231
	 * Decode val stored in cache
232
	 *
233
	 * Lifetime get/set various by cache type, assign in subclass
234
	 *
235
	 * @param	string	$str			Str read from cache
236
	 * @return	mixed
237
	 */
238
	public function ValDecode ($str) {
239
		if (1 == $this->aCfg['cache-store-method']) {
240
			// Json to array
241
			return json_decode($str, true);
242
		}
243
		elseif (2 == $this->aCfg['cache-store-method']) {
244
			// Json to object
245
			return json_decode($str, false);
246
		}
247
		else {
248
			// Cache store method = 0 or other, return raw.
249
			return $str;
250
		}
251
	} // end of func ValDecode
252
253
254
	/**
255
	 * Encode val to store in cache
256
	 *
257
	 * Lifetime get/set various by cache type, assign in subclass
258
	 *
259
	 * @param	mixed	$val
260
	 * @return	string
261
	 */
262
	public function ValEncode ($val) {
263
		if (1 == $this->aCfg['cache-store-method']
264
			|| 2 == $this->aCfg['cache-store-method']) {
265
			return JsonEncodeUnicode($val);
0 ignored issues
show
Deprecated Code introduced by
The function JsonEncodeUnicode() has been deprecated with message: Use Fwlib\Util\Json::encodeUnicode()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
266
		}
267
		else {
268
			// Raw
269
			return $val;
270
		}
271
	} // end of func ValEncode
272
273
274
	/**
275
	 * Get or increase version number
276
	 *
277
	 * Mostly used in memcached for batch delete items
278
	 *
279
	 * @param	string	$key
280
	 * @param	int		$i_increment
281
	 * @param	int		$i_max
282
	 * @return	int
283
	 */
284
	public function Ver ($key, $i_increment = 0, $i_max = 65535) {
285
		$i = $this->Get($key);
0 ignored issues
show
It seems like you code against a specific sub-type and not the parent class Cache as the method Get() does only exist in the following sub-classes of Cache: CacheFile, CacheMemcached. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
286
		if (empty($i)) {
287
			$i = 1;
288
			$this->Set($key, $i, 0);
0 ignored issues
show
It seems like you code against a specific sub-type and not the parent class Cache as the method Set() does only exist in the following sub-classes of Cache: CacheFile, CacheMemcached. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
289
		}
290
291
		if (0 != $i_increment) {
292
			$i += $i_increment;
293
			if ($i_max < $i)
294
				$i = 1;
295
			$this->Set($key, $i, 0);
0 ignored issues
show
It seems like you code against a specific sub-type and not the parent class Cache as the method Set() does only exist in the following sub-classes of Cache: CacheFile, CacheMemcached. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
296
		}
297
298
		return $i;
299
	} // end of func Ver
300
301
302
} // end of class Cache
303
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
304