PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
← All changes | src/traits/io.php +41 -25 5.7.2 → 6.3.0 View file →
@@ -150,9 +150,10 @@
150 150 *
151 151 * @return bool
152 152 */
153 153 protected function compare_hashes_on_different_os( $file_path, $file_hash ) {
154 - if ( hash_equals( md5_file( $file_path ), $file_hash ) ) {
154 + $hashed_file = md5_file( $file_path );
155 + if ( false !== $hashed_file && hash_equals( $hashed_file, $file_hash ) ) {
155 156 return true;
156 157 }
157 158 if ( hash_equals( $this->hash_file( $file_path, 'linux' ), $file_hash ) ) {
158 159 return true;
@@ -177,9 +178,9 @@
177 178 return $this->compare_hashes_on_different_os( $file_path, $file_hash );
178 179 } elseif ( is_array( $file_hash ) ) {
179 180 // Sometimes file has some hashes.
180 181 foreach ( $file_hash as $hash_value ) {
181 - if ( $this->compare_hashes_on_different_os( $file_path, $hash_value ) ) {
182 + if ( is_string( $hash_value ) && $this->compare_hashes_on_different_os( $file_path, $hash_value ) ) {
182 183 return true;
183 184 }
184 185 }
185 186
@@ -225,57 +226,72 @@
225 226
226 227 /**
227 228 * Retrieves the lock file path used in scanning.
228 229 *
230 + * @param string $lock_filename The lock file name.
231 + *
229 232 * @return string The lock file path.
230 233 *
231 234 * @throws \RuntimeException If the lock file name is not defined.
232 235 */
233 - protected function get_lock_path(): string {
234 - if ( '' === $this->lock_filename ) {
236 + protected function get_lock_path( string $lock_filename ): string {
237 + if ( '' === $lock_filename ) {
235 238 throw new \RuntimeException( 'Lock file name must be defined in the class using IO trait.' );
236 239 }
237 240
238 - return $this->get_tmp_path() . DIRECTORY_SEPARATOR . $this->lock_filename;
241 + return $this->get_tmp_path() . DIRECTORY_SEPARATOR . $lock_filename;
239 242 }
240 243
241 244 /**
242 - * Create a file lock, so we can check if a process already running.
243 - */
244 - public function create_lock() {
245 - $this->remove_lock();
246 - file_put_contents( $this->get_lock_path(), time(), LOCK_EX ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
247 - }
248 -
249 - /**
250 245 * Delete file lock.
246 + *
247 + * @param string $lock_filename The lock file name.
251 248 */
252 - public function remove_lock() {
253 - if ( file_exists( $this->get_lock_path() ) ) {
254 - wp_delete_file( $this->get_lock_path() );
249 + public function remove_lock( string $lock_filename ) {
250 + $lock_path = $this->get_lock_path( $lock_filename );
251 + if ( file_exists( $lock_path ) ) {
252 + wp_delete_file( $lock_path );
255 253 }
256 254 }
257 255
258 256 /**
259 - * Check if a lock is valid.
257 + * Atomically acquire a file lock.
260 258 *
261 - * @return bool
259 + * @param string $lock_filename The lock filename.
260 + *
261 + * @return bool True when the lock is acquired.
262 262 */
263 - public function has_lock(): bool {
263 + public function try_create_lock( string $lock_filename ): bool {
264 264 global $wp_filesystem;
265 - // Initialize the WP filesystem, no more using 'file-put-contents' function.
265 +
266 266 if ( ! $wp_filesystem instanceof WP_Filesystem_Base ) {
267 267 require_once ABSPATH . '/wp-admin/includes/file.php';
268 268 WP_Filesystem();
269 269 }
270 - if ( ! file_exists( $this->get_lock_path() ) ) {
271 - return false;
270 +
271 + $lock_path = $this->get_lock_path( $lock_filename );
272 +
273 + if ( is_file( $lock_path ) ) {
274 + $time = (int) $wp_filesystem->get_contents( $lock_path );
275 +
276 + // Existing lock is still valid.
277 + if ( ( $time + 90 ) >= time() ) {
278 + return false;
279 + }
280 +
281 + // Remove stale lock.
282 + wp_delete_file( $lock_path );
272 283 }
273 - $time = $wp_filesystem->get_contents( $this->get_lock_path() );
274 - if ( strtotime( '+90 seconds', $time ) < time() ) {
275 - // Usually a timeout window is 30 seconds, so we should allow lock at 1.30min for safe.
284 +
285 + $handle = @fopen( $lock_path, 'x' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen, WordPress.PHP.NoSilencedErrors.Discouraged
286 +
287 + if ( false === $handle ) {
288 + // Another process acquired the lock.
276 289 return false;
277 290 }
291 +
292 + fwrite( $handle, (string) time() ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
293 + fclose( $handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
278 294
279 295 return true;
280 296 }
281 297