소스 검색

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.
Max Wipfli 4 년 전
부모
커밋
1f792faf34
3개의 변경된 파일35개의 추가작업 그리고 1개의 파일을 삭제
  1. 4 1
      Kernel/FileSystem/VirtualFileSystem.cpp
  2. 28 0
      Kernel/KLexicalPath.cpp
  3. 3 0
      Kernel/KLexicalPath.h

+ 4 - 1
Kernel/FileSystem/VirtualFileSystem.cpp

@@ -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)) {

+ 28 - 0
Kernel/KLexicalPath.cpp

@@ -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 - 0
Kernel/KLexicalPath.h

@@ -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&);
+
 }