From 4bf2cd56534892d1767b2e066699ccfd039c0de3 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Mon, 25 May 2026 19:53:21 -0400 Subject: [PATCH] fix: avoid filesystem null reads --- inc/Runtime/WordPressRuntimeInspector.php | 15 ++++----------- inc/Workspace/WorkspaceWorktreeLifecycle.php | 17 ++++------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/inc/Runtime/WordPressRuntimeInspector.php b/inc/Runtime/WordPressRuntimeInspector.php index 3d00796f..496f1152 100644 --- a/inc/Runtime/WordPressRuntimeInspector.php +++ b/inc/Runtime/WordPressRuntimeInspector.php @@ -125,7 +125,6 @@ public function ls( array $input ): array|\WP_Error { * @return array|\WP_Error */ public function read( array $input ): array|\WP_Error { - global $wp_filesystem; $path = (string) ( $input['path'] ?? '' ); $max_size = $this->clampInt($input['max_size'] ?? self::DEFAULT_MAX_READ_SIZE, 1, self::DEFAULT_MAX_READ_SIZE); $offset = $this->clampInt($input['offset'] ?? 1, 1, PHP_INT_MAX); @@ -151,11 +150,8 @@ public function read( array $input ): array|\WP_Error { ); } - if ( is_readable($resolved['real_path']) ) { - $sample = $wp_filesystem->get_contents($resolved['real_path'], false, null, 0, min($size, 8192)); - } else { - $sample = false; - } + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents,WordPress.PHP.NoSilencedErrors.Discouraged -- Path is validated by resolveAllowedPath(). + $sample = @file_get_contents($resolved['real_path'], false, null, 0, min($size, 8192)); if ( false === $sample ) { return new \WP_Error('datamachine_runtime_unreadable', 'File is not readable.'); } @@ -164,11 +160,8 @@ public function read( array $input ): array|\WP_Error { return new \WP_Error('datamachine_runtime_binary_file', 'Binary file reading is denied.', array( 'path' => $resolved['relative_path'] )); } - if ( is_readable($resolved['real_path']) ) { - $lines = file($resolved['real_path'], FILE_IGNORE_NEW_LINES); - } else { - $lines = false; - } + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file,WordPress.PHP.NoSilencedErrors.Discouraged -- Path is validated by resolveAllowedPath(). + $lines = @file($resolved['real_path'], FILE_IGNORE_NEW_LINES); if ( false === $lines ) { return new \WP_Error('datamachine_runtime_unreadable', 'File is not readable.'); } diff --git a/inc/Workspace/WorkspaceWorktreeLifecycle.php b/inc/Workspace/WorkspaceWorktreeLifecycle.php index 6bd52f20..5cf50ad5 100644 --- a/inc/Workspace/WorkspaceWorktreeLifecycle.php +++ b/inc/Workspace/WorkspaceWorktreeLifecycle.php @@ -1247,7 +1247,6 @@ private function try_rebase_worktree( string $wt_path, array &$response, bool $c * @return string|null Branch name (e.g. `fix/foo`), or null when unknown. */ private function resolve_worktree_branch_from_head_file( string $wt_path ): ?string { - global $wp_filesystem; $git_pointer = rtrim($wt_path, '/') . '/.git'; if ( ! is_file($git_pointer) && ! is_dir($git_pointer) ) { return null; @@ -1255,12 +1254,8 @@ private function resolve_worktree_branch_from_head_file( string $wt_path ): ?str $gitdir = null; if ( is_file($git_pointer) ) { - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reading .git pointer file in a controlled worktree. - if ( is_readable($git_pointer) ) { - $pointer = $wp_filesystem->get_contents($git_pointer); - } else { - $pointer = false; - } + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents,WordPress.PHP.NoSilencedErrors.Discouraged -- Reading .git pointer file in a controlled worktree. + $pointer = @file_get_contents($git_pointer); if ( false === $pointer ) { return null; } @@ -1285,12 +1280,8 @@ private function resolve_worktree_branch_from_head_file( string $wt_path ): ?str return null; } - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reading .git HEAD file in a controlled worktree. - if ( is_readable($head_file) ) { - $head = $wp_filesystem->get_contents($head_file); - } else { - $head = false; - } + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents,WordPress.PHP.NoSilencedErrors.Discouraged -- Reading .git HEAD file in a controlled worktree. + $head = @file_get_contents($head_file); if ( false === $head ) { return null; }