Check buffer state is not destroyed before internally calling unmap

Calling UnmapInternal would set the state to Unmapped, allowing the
buffer to be mapped again even though it is destroyed.

Bug: chromium:1388920
Change-Id: Ibb4da332bafd44a0d4900c8ea5bfbd674bbc35e0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/111121
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/Buffer.cpp b/src/dawn/native/Buffer.cpp
index 87db6ac..fd13a3c 100644
--- a/src/dawn/native/Buffer.cpp
+++ b/src/dawn/native/Buffer.cpp
@@ -422,6 +422,9 @@
 }
 
 void BufferBase::Unmap() {
+    if (mState == BufferState::Destroyed) {
+        return;
+    }
     UnmapInternal(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback);
 }
 
diff --git a/src/dawn/tests/unittests/validation/BufferValidationTests.cpp b/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
index c943c4e..3b2f3ae 100644
--- a/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
@@ -528,6 +528,22 @@
     }
 }
 
+// Test that unmap then mapping a destroyed buffer is an error.
+// Regression test for crbug.com/1388920.
+TEST_F(BufferValidationTest, MapDestroyedBufferAfterUnmap) {
+    wgpu::Buffer buffer = CreateMapReadBuffer(4);
+    buffer.Destroy();
+    buffer.Unmap();
+
+    ASSERT_DEVICE_ERROR(buffer.MapAsync(
+        wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+        [](WGPUBufferMapAsyncStatus status, void* userdata) {
+            EXPECT_EQ(WGPUBufferMapAsyncStatus_Error, status);
+        },
+        nullptr));
+    WaitForAllOperations(device);
+}
+
 // Test that it is valid to submit a buffer in a queue with a map usage if it is unmapped
 TEST_F(BufferValidationTest, SubmitBufferWithMapUsage) {
     wgpu::BufferDescriptor descriptorA;