@@ -105,11 +105,11 @@ public function unbind( string $slug, bool $purge = false ): array|\WP_Error {
105105 $ purged = false ;
106106
107107 if ( $ purge && is_dir ($ absolute ) ) {
108- $ abspath = rtrim ( ABSPATH , ' / ' );
109- $ validation = PathSecurity::validateContainment ($ absolute , $ abspath );
108+ $ root = $ binding -> resolveContainmentRoot ( );
109+ $ validation = PathSecurity::validateContainment ($ absolute , $ root );
110110 if ( ! $ validation ['valid ' ] ) {
111111 return new \WP_Error (
112- 'path_outside_abspath ' ,
112+ 'path_outside_binding_root ' ,
113113 sprintf ('Refusing to purge "%s": %s ' , $ absolute , $ validation ['message ' ] ?? 'containment failed ' ),
114114 array ( 'status ' => 403 )
115115 );
@@ -255,9 +255,9 @@ public function updatePolicy( string $slug, array $patch ): array|\WP_Error {
255255 * be leading-slash, no traversal, not sensitive.
256256 */
257257 private function validateLocalPath ( GitSyncBinding $ binding ): true |\WP_Error {
258- $ relative = ltrim ( str_replace ( '\\' , ' / ' , $ binding ->local_path ), ' / ' );
258+ $ relative = GitSyncBinding:: normalizeRelativePath ( $ binding ->local_path );
259259 if ( '' === $ relative ) {
260- return new \WP_Error ('invalid_local_path ' , 'local_path cannot resolve to ABSPATH itself. ' , array ( 'status ' => 400 ));
260+ return new \WP_Error ('invalid_local_path ' , 'local_path cannot resolve to the binding root itself. ' , array ( 'status ' => 400 ));
261261 }
262262 if ( PathSecurity::hasTraversal ($ relative ) ) {
263263 return new \WP_Error ('path_traversal ' , 'local_path contains traversal segments (`.`, `..`). ' , array ( 'status ' => 400 ));
@@ -267,12 +267,12 @@ private function validateLocalPath( GitSyncBinding $binding ): true|\WP_Error {
267267 }
268268
269269 // If the target already exists, run the symlink-safe check too.
270- $ abspath = rtrim ( ABSPATH , ' / ' );
271- $ absolute = $ abspath . ' / ' . rtrim ( $ relative , ' / ' );
270+ $ root = $ binding -> resolveContainmentRoot ( );
271+ $ absolute = $ binding -> resolveAbsolutePath ( );
272272 if ( is_dir ($ absolute ) ) {
273- $ containment = PathSecurity::validateContainment ($ absolute , $ abspath );
273+ $ containment = PathSecurity::validateContainment ($ absolute , $ root );
274274 if ( ! $ containment ['valid ' ] ) {
275- return new \WP_Error ('path_outside_abspath ' , sprintf ('local_path resolves outside ABSPATH : %s ' , $ containment ['message ' ] ?? '' ), array ( 'status ' => 403 ));
275+ return new \WP_Error ('path_outside_binding_root ' , sprintf ('local_path resolves outside its binding root : %s ' , $ containment ['message ' ] ?? '' ), array ( 'status ' => 403 ));
276276 }
277277 }
278278
0 commit comments