Skip to content

Commit 84e859c

Browse files
committed
attempt to fix path resolution
1 parent 2556ac7 commit 84e859c

File tree

1 file changed

+27
-22
lines changed

1 file changed

+27
-22
lines changed

src/Storages/ObjectStorage/Utils.cpp

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -269,23 +269,8 @@ std::string normalizePathToStorageRoot(const std::string & table_location, const
269269
if (!rel_path.empty() && rel_path.front() == '/')
270270
rel_path = rel_path.substr(1);
271271

272-
if (!rel_path.empty() && !base.key.empty())
273-
{
274-
if (rel_path == base.key || rel_path.starts_with(base.key + "/"))
275-
{
276-
std::filesystem::path fs_path(rel_path);
277-
std::filesystem::path normalized = fs_path.lexically_normal();
278-
279-
std::string result = normalized.string();
280-
std::replace(result.begin(), result.end(), '\\', '/');
281-
282-
while (!result.empty() && result.front() == '/')
283-
result = result.substr(1);
284-
285-
return result;
286-
}
287-
}
288-
272+
// First, try combining and normalizing to see if the path resolves outside the table location
273+
// This handles cases where paths use ".." to go up from table location to shared parent
289274
std::string combined = base.key;
290275
if (!combined.empty() && combined.back() != '/')
291276
combined += '/';
@@ -295,13 +280,33 @@ std::string normalizePathToStorageRoot(const std::string & table_location, const
295280
std::filesystem::path fs_path(combined);
296281
std::filesystem::path normalized = fs_path.lexically_normal();
297282

298-
std::string result = normalized.string();
299-
std::replace(result.begin(), result.end(), '\\', '/'); // Unlikely but some may use Windows paths
283+
std::string normalized_result = normalized.string();
284+
std::replace(normalized_result.begin(), normalized_result.end(), '\\', '/');
300285

301-
while (!result.empty() && result.front() == '/')
302-
result = result.substr(1);
286+
while (!normalized_result.empty() && normalized_result.front() == '/')
287+
normalized_result = normalized_result.substr(1);
288+
289+
// Check if the normalized path still starts with base.key (meaning it's under table location)
290+
// or if it doesn't (meaning it resolved outside, e.g., via "..")
291+
if (!normalized_result.empty() && !base.key.empty())
292+
{
293+
// If normalized path doesn't start with base.key, it means the original path
294+
// used ".." to go outside the table location - use the normalized path as-is
295+
if (!normalized_result.starts_with(base.key + "/") && normalized_result != base.key)
296+
{
297+
return normalized_result;
298+
}
299+
300+
// If normalized path starts with base.key, check if original path already included it
301+
// This handles cases where paths in metadata are already relative to storage root
302+
if (rel_path == base.key || rel_path.starts_with(base.key + "/"))
303+
{
304+
// Path already includes table location, return normalized version
305+
return normalized_result;
306+
}
307+
}
303308

304-
return result;
309+
return normalized_result;
305310
}
306311

307312
std::string makeAbsolutePath(const std::string & table_location, const std::string & path)

0 commit comments

Comments
 (0)