@@ -1201,19 +1201,43 @@ private static function get_package_name_and_version_from_dir_package( $dir_pack
12011201 /**
12021202 * Checks whether a path is inside (or equal to) a given parent directory.
12031203 *
1204- * Uses string-based normalisation so it works even when the paths do not
1205- * exist on the filesystem yet.
1204+ * Resolves '.' and '..' segments without touching the filesystem so it
1205+ * works even when the paths do not exist yet. Uses a case-insensitive
1206+ * comparison on Windows where the filesystem is case-insensitive.
12061207 *
12071208 * @param string $path Path to test.
12081209 * @param string $parent_dir Parent directory to test against.
12091210 * @return bool True when $path is inside $parent_dir.
12101211 */
12111212 private static function is_child_path ( $ path , $ parent_dir ) {
1212- $ normalized_path = rtrim ( Path::normalize ( $ path ), '/ ' ) . '/ ' ;
1213- $ normalized_parent = rtrim ( Path::normalize ( $ parent_dir ), '/ ' ) . '/ ' ;
1213+ $ normalized_path = self ::resolve_dot_segments ( rtrim ( str_replace ( '\\' , '/ ' , $ path ), '/ ' ) ) . '/ ' ;
1214+ $ normalized_parent = self ::resolve_dot_segments ( rtrim ( str_replace ( '\\' , '/ ' , $ parent_dir ), '/ ' ) ) . '/ ' ;
1215+ if ( DIRECTORY_SEPARATOR === '\\' ) {
1216+ return 0 === stripos ( $ normalized_path , $ normalized_parent );
1217+ }
12141218 return 0 === strpos ( $ normalized_path , $ normalized_parent );
12151219 }
12161220
1221+ /**
1222+ * Resolves '.' and '..' segments in a path without touching the filesystem.
1223+ *
1224+ * @param string $path Forward-slash path to resolve.
1225+ * @return string Resolved path.
1226+ */
1227+ private static function resolve_dot_segments ( $ path ) {
1228+ $ is_absolute = isset ( $ path [0 ] ) && '/ ' === $ path [0 ];
1229+ $ result = [];
1230+ foreach ( explode ( '/ ' , $ path ) as $ part ) {
1231+ if ( '.. ' === $ part ) {
1232+ array_pop ( $ result );
1233+ } elseif ( '. ' !== $ part && '' !== $ part ) {
1234+ $ result [] = $ part ;
1235+ }
1236+ }
1237+ $ resolved = implode ( '/ ' , $ result );
1238+ return $ is_absolute ? '/ ' . $ resolved : $ resolved ;
1239+ }
1240+
12171241 /**
12181242 * Gets the WP-CLI packages composer.json object.
12191243 */
0 commit comments