Skip to content

Commit

Permalink
Kernel: Add KLexicalPath::try_join and use it
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
MaxWipfli authored and awesomekling committed Jul 7, 2021
1 parent ee342f5 commit 1f792fa
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
5 changes: 4 additions & 1 deletion Kernel/FileSystem/VirtualFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
28 changes: 28 additions & 0 deletions Kernel/KLexicalPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

}
3 changes: 3 additions & 0 deletions Kernel/KLexicalPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#include <AK/StringView.h>
#include <Kernel/KString.h>

namespace Kernel::KLexicalPath {

Expand All @@ -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&);

}

0 comments on commit 1f792fa

Please sign in to comment.