PluginProbe
404 Solution / 4.2.0
404 Solution v4.2.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / php / FileSync.php

FileSync.php in 404 Solution 4.2.0, at includes/php/FileSync.php

76 lines 1.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3
4 if (!defined('ABSPATH')) {
5 exit;
6 }
7
8 class ABJ_404_Solution_FileSync {
9
10 /** @var self|null */
11 private static $instance = null;
12
13 /** @return self */
14 public static function getInstance(): self {
15 if (self::$instance == null) {
16 self::$instance = new ABJ_404_Solution_FileSync();
17 }
18
19 return self::$instance;
20 }
21
22 /**
23 * @param string $key
24 * @return string
25 */
26 function getSyncFilePath(string $key): string {
27 $filePath = abj404_getUploadsDir() . 'SYNC_FILE_' . $key . '.txt';
28 return $filePath;
29 }
30
31 /**
32 * @param string $key
33 * @return string
34 */
35 function getOwnerFromFile(string $key): string {
36 $filePath = $this->getSyncFilePath($key);
37 $fileUtils = abj_service('functions');
38
39 // Fixed: TOCTOU race condition - catch exception instead of check-then-read
40 try {
41 $contents = $fileUtils->readFileContents($filePath, false);
42 return $contents;
43 } catch (Exception $e) { // allow-silent-catch: TOCTOU-safe file read; missing or unreadable file returns empty, caller treats as "no lock owner"
44 return "";
45 }
46 }
47
48 /**
49 * @param string $key
50 * @param string $uniqueID
51 * @return void
52 */
53 function writeOwnerToFile(string $key, string $uniqueID): void {
54 $filePath = $this->getSyncFilePath($key);
55
56 // Fixed: Check return value to handle write failures (disk full, permissions, etc.)
57 $result = @file_put_contents($filePath, $uniqueID, LOCK_EX);
58
59 if ($result === false) {
60 throw new Exception("Failed to write lock file: " . $filePath);
61 }
62 }
63
64 /**
65 * @param string $uniqueID
66 * @param string $key
67 * @return void
68 */
69 function releaseLock(string $uniqueID, string $key): void {
70 $filePath = $this->getSyncFilePath($key);
71 $fileUtils = abj_service('functions');
72 $fileUtils->safeUnlink($filePath);
73 }
74
75 }
76