Kernel: Add KLexicalPath::try_join and use it
This adds KLexicalPath::try_join(). As this cannot be done without allocation, it uses KString and can fail. This patch also uses it at one place. All the other cases of String::formatted("{}/{}", ...) currently rely on the return value being a String, which means they cannot easily be converted to use the new API.
This commit is contained in:
parent
ee342f5ec3
commit
1f792faf34
Notes:
sideshowbarker
2024-07-18 10:14:13 +09:00
Author: https://github.com/MaxWipfli Commit: https://github.com/SerenityOS/serenity/commit/1f792faf34f Pull-request: https://github.com/SerenityOS/serenity/pull/8492 Reviewed-by: https://github.com/alimpfard
3 changed files with 35 additions and 1 deletions
|
@ -361,7 +361,10 @@ KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base)
|
|||
KResultOr<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> owner)
|
||||
{
|
||||
auto basename = KLexicalPath::basename(path);
|
||||
if (auto result = validate_path_against_process_veil(String::formatted("{}/{}", parent_custody.absolute_path(), basename), options); result.is_error())
|
||||
auto full_path = KLexicalPath::try_join(parent_custody.absolute_path(), basename);
|
||||
if (!full_path)
|
||||
return ENOMEM;
|
||||
if (auto result = validate_path_against_process_veil(full_path->view(), options); result.is_error())
|
||||
return result;
|
||||
|
||||
if (!is_socket(mode) && !is_fifo(mode) && !is_block_device(mode) && !is_character_device(mode)) {
|
||||
|
|
|
@ -55,4 +55,32 @@ Vector<StringView> parts(StringView const& path)
|
|||
return path.split_view('/');
|
||||
}
|
||||
|
||||
OwnPtr<KString> try_join(StringView const& first, StringView const& second)
|
||||
{
|
||||
VERIFY(is_canonical(first));
|
||||
VERIFY(is_canonical(second));
|
||||
VERIFY(!is_absolute(second));
|
||||
|
||||
if (first == "/"sv) {
|
||||
char* buffer;
|
||||
auto string = KString::try_create_uninitialized(1 + second.length(), buffer);
|
||||
if (!string)
|
||||
return {};
|
||||
buffer[0] = '/';
|
||||
__builtin_memcpy(buffer + 1, second.characters_without_null_termination(), second.length());
|
||||
buffer[string->length()] = 0;
|
||||
return string;
|
||||
} else {
|
||||
char* buffer;
|
||||
auto string = KString::try_create_uninitialized(first.length() + 1 + second.length(), buffer);
|
||||
if (!string)
|
||||
return string;
|
||||
__builtin_memcpy(buffer, first.characters_without_null_termination(), first.length());
|
||||
buffer[first.length()] = '/';
|
||||
__builtin_memcpy(buffer + first.length() + 1, second.characters_without_null_termination(), second.length());
|
||||
buffer[string->length()] = 0;
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/StringView.h>
|
||||
#include <Kernel/KString.h>
|
||||
|
||||
namespace Kernel::KLexicalPath {
|
||||
|
||||
|
@ -16,4 +17,6 @@ StringView basename(StringView const&);
|
|||
StringView dirname(StringView const&);
|
||||
Vector<StringView> parts(StringView const&);
|
||||
|
||||
OwnPtr<KString> try_join(StringView const&, StringView const&);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue