From f64d0b3f263c077bc18920f47fe63524fdc6cd94 Mon Sep 17 00:00:00 2001
From: Yuri Kunde Schlesner <yuriks@yuriks.net>
Date: Wed, 21 Jun 2017 14:27:03 -0700
Subject: [PATCH 1/2] Kernel/IPC: Support translation of null handles

Missed this in my first implementation. Thanks to @wwylele for pointing
out that this was missing.
---
 src/core/hle/kernel/hle_ipc.cpp       | 19 ++++++++++++-------
 src/tests/core/hle/kernel/hle_ipc.cpp | 23 +++++++++++++++++++++++
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 1cac1d0c9..5ebe2eca4 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -67,10 +67,13 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
             ASSERT(i + num_handles <= command_size); // TODO(yuriks): Return error
             for (u32 j = 0; j < num_handles; ++j) {
                 Handle handle = src_cmdbuf[i];
-                SharedPtr<Object> object = src_table.GetGeneric(handle);
-                ASSERT(object != nullptr); // TODO(yuriks): Return error
-                if (descriptor == IPC::DescriptorType::MoveHandle) {
-                    src_table.Close(handle);
+                SharedPtr<Object> object = nullptr;
+                if (handle != 0) {
+                    object = src_table.GetGeneric(handle);
+                    ASSERT(object != nullptr); // TODO(yuriks): Return error
+                    if (descriptor == IPC::DescriptorType::MoveHandle) {
+                        src_table.Close(handle);
+                    }
                 }
 
                 cmd_buf[i++] = AddOutgoingHandle(std::move(object));
@@ -112,9 +115,11 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
             ASSERT(i + num_handles <= command_size);
             for (u32 j = 0; j < num_handles; ++j) {
                 SharedPtr<Object> object = GetIncomingHandle(cmd_buf[i]);
-
-                // TODO(yuriks): Figure out the proper error handling for if this fails
-                Handle handle = dst_table.Create(object).Unwrap();
+                Handle handle = 0;
+                if (object != nullptr) {
+                    // TODO(yuriks): Figure out the proper error handling for if this fails
+                    handle = dst_table.Create(object).Unwrap();
+                }
                 dst_cmdbuf[i++] = handle;
             }
             break;
diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp
index e07a28c5b..6feca2ba3 100644
--- a/src/tests/core/hle/kernel/hle_ipc.cpp
+++ b/src/tests/core/hle/kernel/hle_ipc.cpp
@@ -94,6 +94,18 @@ TEST_CASE("HLERequestContext::PopoulateFromIncomingCommandBuffer", "[core][kerne
         REQUIRE(context.GetIncomingHandle(output[5]) == c);
     }
 
+    SECTION("translates null handles") {
+        const u32_le input[]{
+            IPC::MakeHeader(0, 0, 2), IPC::MoveHandleDesc(1), 0,
+        };
+
+        auto result = context.PopulateFromIncomingCommandBuffer(input, *process, handle_table);
+
+        REQUIRE(result == RESULT_SUCCESS);
+        auto* output = context.CommandBuffer();
+        REQUIRE(context.GetIncomingHandle(output[2]) == nullptr);
+    }
+
     SECTION("translates CallingPid descriptors") {
         const u32_le input[]{
             IPC::MakeHeader(0, 0, 2), IPC::CallingPidDesc(), 0x98989898,
@@ -171,6 +183,17 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
         REQUIRE(handle_table.GetGeneric(output[4]) == b);
     }
 
+    SECTION("translates null handles") {
+        input[0] = IPC::MakeHeader(0, 0, 2);
+        input[1] = IPC::MoveHandleDesc(1);
+        input[2] = context.AddOutgoingHandle(nullptr);
+
+        auto result = context.WriteToOutgoingCommandBuffer(output, *process, handle_table);
+
+        REQUIRE(result == RESULT_SUCCESS);
+        REQUIRE(output[2] == 0);
+    }
+
     SECTION("translates multi-handle descriptors") {
         auto a = MakeObject();
         auto b = MakeObject();

From cdefefc53985dfe1a8117a5c08c9374fb3ad48da Mon Sep 17 00:00:00 2001
From: Yuri Kunde Schlesner <yuriks@yuriks.net>
Date: Thu, 22 Jun 2017 02:21:18 -0700
Subject: [PATCH 2/2] Kernel: Fix typo in test name

---
 src/tests/core/hle/kernel/hle_ipc.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp
index 6feca2ba3..52336d027 100644
--- a/src/tests/core/hle/kernel/hle_ipc.cpp
+++ b/src/tests/core/hle/kernel/hle_ipc.cpp
@@ -18,7 +18,7 @@ static SharedPtr<Object> MakeObject() {
     return Event::Create(ResetType::OneShot);
 }
 
-TEST_CASE("HLERequestContext::PopoulateFromIncomingCommandBuffer", "[core][kernel]") {
+TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") {
     auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair());
     HLERequestContext context(std::move(session));