| @@ -115,13 +115,13 @@ | ||
| 115 | 115 | { |
| 116 | 116 | $basename = basename($wpConfigPath); |
| 117 | 117 | |
| 118 | 118 | if (!file_exists($wpConfigPath)) { |
| 119 | - throw new WPConfigFileNotFoundException("{$basename} does not exist."); | |
| 119 | + throw new WPConfigFileNotFoundException("{$basename} does not exist."); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- JSON-RPC error payload, JSON-encoded on output, never rendered as HTML; escaping here would corrupt message bytes | |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | - if (!is_writable($wpConfigPath)) { | |
| 123 | - throw new WPConfigFileNotWritableException("{$basename} is not writable."); | |
| 122 | + if (!wp_is_writable($wpConfigPath)) { | |
| 123 | + throw new WPConfigFileNotWritableException("{$basename} is not writable."); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- JSON-RPC error payload, JSON-encoded on output, never rendered as HTML; escaping here would corrupt message bytes | |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | 126 | $this->wpConfigPath = $wpConfigPath; |
| 127 | 127 | } |
| @@ -149,9 +149,9 @@ | ||
| 149 | 149 | $this->wpConfigSrc = str_replace(["\n\r", "\r"], "\n", $wpConfigSrc); |
| 150 | 150 | $this->wpConfigs = $this->parseWpConfig($this->wpConfigSrc); |
| 151 | 151 | |
| 152 | 152 | if (!isset($this->wpConfigs[$type])) { |
| 153 | - throw new WPConfigInvalidTypeException("Config type '{$type}' does not exist."); | |
| 153 | + throw new WPConfigInvalidTypeException("Config type '{$type}' does not exist."); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- JSON-RPC error payload, JSON-encoded on output, never rendered as HTML; escaping here would corrupt message bytes | |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | return isset($this->wpConfigs[$type][$name]); |
| 157 | 157 | } |
| @@ -334,9 +334,9 @@ | ||
| 334 | 334 | if ($raw && '' === trim($value)) { |
| 335 | 335 | throw new WPConfigInvalidValueException('Raw value for empty string not supported.'); |
| 336 | 336 | } |
| 337 | 337 | |
| 338 | - return ($raw) ? $value : var_export($value, true); | |
| 338 | + return ($raw) ? $value : var_export($value, true); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export -- unreachable in production | |
| 339 | 339 | } |
| 340 | 340 | |
| 341 | 341 | /** |
| 342 | 342 | * Normalizes the source output for a name/value pair. |
| @@ -355,9 +355,9 @@ | ||
| 355 | 355 | $placeholder = "define( '%s', %s );"; |
| 356 | 356 | } elseif ('variable' === $type) { |
| 357 | 357 | $placeholder = '$%s = %s;'; |
| 358 | 358 | } else { |
| 359 | - throw new WPConfigNormalizationException("Unable to normalize config type '{$type}'."); | |
| 359 | + throw new WPConfigNormalizationException("Unable to normalize config type '{$type}'."); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- JSON-RPC error payload, JSON-encoded on output, never rendered as HTML; escaping here would corrupt message bytes | |
| 360 | 360 | } |
| 361 | 361 | |
| 362 | 362 | return sprintf($placeholder, $name, $value); |
| 363 | 363 | } |
| @@ -463,12 +463,12 @@ | ||
| 463 | 463 | // The atomic path needs a writable directory, while the constructor only |
| 464 | 464 | // guarantees a writable file. WordPress' recommended "wp-config.php one level |
| 465 | 465 | // above the web root" layout commonly has exactly that shape, and earlier |
| 466 | 466 | // versions wrote fine there, so fall back rather than refusing to save. |
| 467 | - if (!is_writable($dir)) { | |
| 467 | + if (!wp_is_writable($dir)) { | |
| 468 | 468 | // Logged because the fallback gives up atomicity: a crash mid-write can |
| 469 | 469 | // leave wp-config.php short, so affected hosts should be identifiable. |
| 470 | - error_log('MetaSync: ' . $dir . ' is not writable; writing wp-config.php in place' | |
| 470 | + error_log('MetaSync: ' . $dir . ' is not writable; writing wp-config.php in place' // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 471 | 471 | . ' (non-atomic) instead of via an atomic replace.'); |
| 472 | 472 | return $this->saveInPlace($targetPath, $contents); |
| 473 | 473 | } |
| 474 | 474 | |
| @@ -485,9 +485,9 @@ | ||
| 485 | 485 | $tempFile = $dir . '/.metasync-tmp-' . bin2hex(random_bytes(8)); |
| 486 | 486 | |
| 487 | 487 | try { |
| 488 | 488 | // 'x' mode fails if the path already exists, so we never clobber another file. |
| 489 | - $handle = @fopen($tempFile, 'x'); | |
| 489 | + $handle = @fopen($tempFile, 'x'); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- streaming file I/O; WP_Filesystem cannot return a raw stream handle | |
| 490 | 490 | if (false === $handle) { |
| 491 | 491 | // The directory looked writable but the create failed anyway. |
| 492 | 492 | return $this->saveInPlace($targetPath, $contents); |
| 493 | 493 | } |
| @@ -492,17 +492,17 @@ | ||
| 492 | 492 | return $this->saveInPlace($targetPath, $contents); |
| 493 | 493 | } |
| 494 | 494 | |
| 495 | 495 | // Lock the temp file down before any sensitive content is written to it. |
| 496 | - $permissionsLocked = @chmod($tempFile, 0600); | |
| 496 | + $permissionsLocked = @chmod($tempFile, 0600); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chmod -- direct POSIX permission change; WP_Filesystem would prompt for FTP credentials on non-direct hosts | |
| 497 | 497 | $permissionsWrong = PHP_OS_FAMILY !== 'Windows' |
| 498 | 498 | && ((@fileperms($tempFile) & 0777) !== 0600); |
| 499 | 499 | if (!$permissionsLocked || $permissionsWrong) { |
| 500 | - @fclose($handle); | |
| 500 | + @fclose($handle); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- operates on a native stream handle | |
| 501 | 501 | throw new WPConfigSaveException('Could not secure the temporary config file.'); |
| 502 | 502 | } |
| 503 | 503 | |
| 504 | - $written = @fwrite($handle, $contents); | |
| 504 | + $written = @fwrite($handle, $contents); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- operates on a native stream handle | |
| 505 | 505 | $flushed = @fflush($handle); |
| 506 | 506 | |
| 507 | 507 | if (function_exists('fsync')) { |
| 508 | 508 | @fsync($handle); |
| @@ -507,9 +507,9 @@ | ||
| 507 | 507 | if (function_exists('fsync')) { |
| 508 | 508 | @fsync($handle); |
| 509 | 509 | } |
| 510 | 510 | |
| 511 | - $closed = @fclose($handle); | |
| 511 | + $closed = @fclose($handle); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- operates on a native stream handle | |
| 512 | 512 | clearstatcache(true, $tempFile); |
| 513 | 513 | |
| 514 | 514 | // fwrite() can report a full write while the error only surfaces later at |
| 515 | 515 | // flush or close time (a full disk, NFS, EIO). Confirm the bytes actually |
| @@ -525,9 +525,9 @@ | ||
| 525 | 525 | } |
| 526 | 526 | |
| 527 | 527 | // Atomically move the temp file over the config file. The original is only |
| 528 | 528 | // ever replaced by this single call; on failure it remains untouched. |
| 529 | - if (!@rename($tempFile, $targetPath)) { | |
| 529 | + if (!@rename($tempFile, $targetPath)) { // phpcs:ignore WordPress.WP.AlternativeFunctions.rename_rename -- atomic same-filesystem replace; WP_Filesystem::move() needs credential bootstrapping on non-direct hosts | |
| 530 | 530 | throw new WPConfigSaveException('Failed to update the config file.'); |
| 531 | 531 | } |
| 532 | 532 | } finally { |
| 533 | 533 | // A thrown failure, fatal or timeout must never leave a readable copy of |
| @@ -533,9 +533,9 @@ | ||
| 533 | 533 | // A thrown failure, fatal or timeout must never leave a readable copy of |
| 534 | 534 | // wp-config.php sitting next to it. |
| 535 | 535 | clearstatcache(true, $tempFile); |
| 536 | 536 | if (is_file($tempFile)) { |
| 537 | - @unlink($tempFile); | |
| 537 | + wp_delete_file($tempFile); | |
| 538 | 538 | } |
| 539 | 539 | } |
| 540 | 540 | |
| 541 | 541 | // rename() installs a new inode, so the original ownership and mode do not |
| @@ -540,23 +540,23 @@ | ||
| 540 | 540 | |
| 541 | 541 | // rename() installs a new inode, so the original ownership and mode do not |
| 542 | 542 | // carry over. Restore both - ownership best-effort, since only a privileged |
| 543 | 543 | // process may change it - so the file keeps the identity the host expects. |
| 544 | - if (PHP_OS_FAMILY !== 'Windows' && false !== $originalOwner && !@chown($targetPath, $originalOwner)) { | |
| 544 | + if (PHP_OS_FAMILY !== 'Windows' && false !== $originalOwner && !@chown($targetPath, $originalOwner)) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chown -- direct POSIX ownership change; no WordPress API | |
| 545 | 545 | // Common on hosts where wp-config.php is owned by a deploy user and only |
| 546 | 546 | // group-writable by the web user: the file is now owned by the web user and |
| 547 | 547 | // an unprivileged process cannot hand it back. Deploy tooling may lose write |
| 548 | 548 | // access, so make it findable rather than silent. |
| 549 | - error_log('MetaSync: wp-config.php is no longer owned by uid ' . $originalOwner | |
| 549 | + error_log('MetaSync: wp-config.php is no longer owned by uid ' . $originalOwner // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 550 | 550 | . ' after being rewritten, and ownership could not be restored.'); |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | 553 | if (PHP_OS_FAMILY !== 'Windows' && false !== $originalGroup) { |
| 554 | - @chgrp($targetPath, $originalGroup); | |
| 554 | + @chgrp($targetPath, $originalGroup); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chgrp -- direct POSIX group change; no WordPress API | |
| 555 | 555 | } |
| 556 | 556 | |
| 557 | 557 | if ($originalPerms) { |
| 558 | - @chmod($targetPath, $originalPerms); | |
| 558 | + @chmod($targetPath, $originalPerms); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_chmod -- direct POSIX permission change; WP_Filesystem would prompt for FTP credentials on non-direct hosts | |
| 559 | 559 | } |
| 560 | 560 | |
| 561 | 561 | return true; |
| 562 | 562 | } |
| @@ -583,9 +583,9 @@ | ||
| 583 | 583 | if (false === $mtime || abs(time() - $mtime) < self::TEMP_MAX_AGE) { |
| 584 | 584 | continue; |
| 585 | 585 | } |
| 586 | 586 | |
| 587 | - @unlink($temp); | |
| 587 | + wp_delete_file($temp); | |
| 588 | 588 | } |
| 589 | 589 | } |
| 590 | 590 | |
| 591 | 591 | /** |
| @@ -625,9 +625,9 @@ | ||
| 625 | 625 | if (strlen($this->wpConfigSrc) !== $restored) { |
| 626 | 626 | // Both the write and the rollback failed, so the file on disk is |
| 627 | 627 | // very likely truncated and the site will not boot. Say so plainly - |
| 628 | 628 | // there is deliberately no backup copy to restore from. |
| 629 | - error_log('MetaSync: wp-config.php may be truncated at ' . $targetPath | |
| 629 | + error_log('MetaSync: wp-config.php may be truncated at ' . $targetPath // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 630 | 630 | . ' - restore it manually.'); |
| 631 | 631 | throw new WPConfigSaveException( |
| 632 | 632 | 'Failed to update the config file, and wp-config.php may now be incomplete. Please check it.' |
| 633 | 633 | ); |
| @@ -730,9 +730,9 @@ | ||
| 730 | 730 | self::$configArgs['anchor'] = $anchor; |
| 731 | 731 | self::$configArgs['placement'] = 'after'; |
| 732 | 732 | } |
| 733 | 733 | |
| 734 | - if (!is_writable(self::$configfilePath)) { | |
| 734 | + if (!wp_is_writable(self::$configfilePath)) { | |
| 735 | 735 | $this->setConfigError('Config file not writable'); |
| 736 | 736 | return; |
| 737 | 737 | } |
| 738 | 738 | |
| @@ -798,9 +798,9 @@ | ||
| 798 | 798 | { |
| 799 | 799 | $this->partialWrite = false; |
| 800 | 800 | |
| 801 | 801 | if (!$this->isReady()) { |
| 802 | - error_log('MetaSync: skipped wp-config.php debug constants - ' | |
| 802 | + error_log('MetaSync: skipped wp-config.php debug constants - ' // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 803 | 803 | . ($this->configError !== '' ? $this->configError : 'the file is not writable.')); |
| 804 | 804 | return false; |
| 805 | 805 | } |
| 806 | 806 | |
| @@ -839,9 +839,9 @@ | ||
| 839 | 839 | $key = strtoupper(sanitize_key($constant['name'])); |
| 840 | 840 | |
| 841 | 841 | // Whitelist validation - only allow specific constants |
| 842 | 842 | if (!in_array($key, $allowedConstants, true)) { |
| 843 | - error_log('MetaSync: Attempted to modify non-whitelisted constant: ' . $key); | |
| 843 | + error_log('MetaSync: Attempted to modify non-whitelisted constant: ' . $key); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- unreachable in production | |
| 844 | 844 | continue; |
| 845 | 845 | } |
| 846 | 846 | |
| 847 | 847 | if (empty($key)) { |
| @@ -892,9 +892,9 @@ | ||
| 892 | 892 | $message .= ' Debug constants are still live in wp-config.php, so it is' |
| 893 | 893 | . ' partially updated.'; |
| 894 | 894 | } |
| 895 | 895 | |
| 896 | - error_log('MetaSync: ' . $message); | |
| 896 | + error_log('MetaSync: ' . $message); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 897 | 897 | $this->setConfigError($message); |
| 898 | 898 | return false; |
| 899 | 899 | } |
| 900 | 900 | |
| @@ -918,9 +918,9 @@ | ||
| 918 | 918 | } |
| 919 | 919 | } |
| 920 | 920 | } |
| 921 | 921 | |
| 922 | - error_log('MetaSync: Error updating wp-config.php - ' . $e->getMessage()); | |
| 922 | + error_log('MetaSync: Error updating wp-config.php - ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 923 | 923 | $this->setConfigError('Could not update wp-config.php: ' . $e->getMessage()); |
| 924 | 924 | return false; |
| 925 | 925 | } |
| 926 | 926 | } |
| @@ -987,9 +987,9 @@ | ||
| 987 | 987 | |
| 988 | 988 | try { |
| 989 | 989 | return $this->configFileManager->exists('constant', strtoupper($constant)); |
| 990 | 990 | } catch (\Throwable $e) { |
| 991 | - error_log('MetaSync: Error reading wp-config.php - ' . $e->getMessage()); | |
| 991 | + error_log('MetaSync: Error reading wp-config.php - ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 992 | 992 | return false; |
| 993 | 993 | } |
| 994 | 994 | } |
| 995 | 995 | |
| @@ -1010,9 +1010,9 @@ | ||
| 1010 | 1010 | if ($this->configFileManager->exists('constant', strtoupper($constant))) { |
| 1011 | 1011 | return $this->configFileManager->getValue('constant', strtoupper($constant)); |
| 1012 | 1012 | } |
| 1013 | 1013 | } catch (\Throwable $e) { |
| 1014 | - error_log('MetaSync: Error reading wp-config.php - ' . $e->getMessage()); | |
| 1014 | + error_log('MetaSync: Error reading wp-config.php - ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 1015 | 1015 | } |
| 1016 | 1016 | |
| 1017 | 1017 | return null; |
| 1018 | 1018 | } |
| @@ -1038,9 +1038,9 @@ | ||
| 1038 | 1038 | $value = $value ? 'true' : 'false'; |
| 1039 | 1039 | } |
| 1040 | 1040 | return $this->configFileManager->update('constant', strtoupper($key), $value, $option); |
| 1041 | 1041 | } catch (\Throwable $e) { |
| 1042 | - error_log('MetaSync: Error updating wp-config.php - ' . $e->getMessage()); | |
| 1042 | + error_log('MetaSync: Error updating wp-config.php - ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 1043 | 1043 | return false; |
| 1044 | 1044 | } |
| 1045 | 1045 | } |
| 1046 | 1046 | |