From 4f7d8d222636e1d08684ecf00baa6e7af5e3526c Mon Sep 17 00:00:00 2001
From: Antoine du Hamel <duhamelantoine1995@gmail.com>
Date: Mon, 6 Feb 2023 14:15:22 +0100
Subject: [PATCH] lib: tighten `AbortSignal.prototype.throwIfAborted`
 implementation

---
 lib/internal/abort_controller.js      | 13 +++++++------
 test/parallel/test-abortcontroller.js | 17 +++++++++++++++++
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/lib/internal/abort_controller.js b/lib/internal/abort_controller.js
index 7a4381ecd13cb3..a233f268c559c6 100644
--- a/lib/internal/abort_controller.js
+++ b/lib/internal/abort_controller.js
@@ -94,7 +94,7 @@ function customInspect(self, obj, depth, options) {
   return `${self.constructor.name} ${inspect(obj, opts)}`;
 }
 
-function validateAbortSignal(obj) {
+function validateThisAbortSignal(obj) {
   if (obj?.[kAborted] === undefined)
     throw new ERR_INVALID_THIS('AbortSignal');
 }
@@ -132,7 +132,7 @@ class AbortSignal extends EventTarget {
    * @type {boolean}
    */
   get aborted() {
-    validateAbortSignal(this);
+    validateThisAbortSignal(this);
     return !!this[kAborted];
   }
 
@@ -140,13 +140,14 @@ class AbortSignal extends EventTarget {
    * @type {any}
    */
   get reason() {
-    validateAbortSignal(this);
+    validateThisAbortSignal(this);
     return this[kReason];
   }
 
   throwIfAborted() {
-    if (this.aborted) {
-      throw this.reason;
+    validateThisAbortSignal(this);
+    if (this[kAborted]) {
+      throw this[kReason];
     }
   }
 
@@ -202,7 +203,7 @@ class AbortSignal extends EventTarget {
   }
 
   [kTransfer]() {
-    validateAbortSignal(this);
+    validateThisAbortSignal(this);
     const aborted = this.aborted;
     if (aborted) {
       const reason = this.reason;
diff --git a/test/parallel/test-abortcontroller.js b/test/parallel/test-abortcontroller.js
index 097d632afa7d1c..ce6c72f4294043 100644
--- a/test/parallel/test-abortcontroller.js
+++ b/test/parallel/test-abortcontroller.js
@@ -254,3 +254,20 @@ const { setTimeout: sleep } = require('timers/promises');
   const ac = new AbortController();
   ac.signal.throwIfAborted();
 }
+
+{
+  const originalDesc = Reflect.getOwnPropertyDescriptor(AbortSignal.prototype, 'aborted');
+  const actualReason = new Error();
+  Reflect.defineProperty(AbortSignal.prototype, 'aborted', { value: false });
+  throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
+  Reflect.defineProperty(AbortSignal.prototype, 'aborted', originalDesc);
+}
+
+{
+  const originalDesc = Reflect.getOwnPropertyDescriptor(AbortSignal.prototype, 'reason');
+  const actualReason = new Error();
+  const fakeExcuse = new Error();
+  Reflect.defineProperty(AbortSignal.prototype, 'reason', { value: fakeExcuse });
+  throws(() => AbortSignal.abort(actualReason).throwIfAborted(), actualReason);
+  Reflect.defineProperty(AbortSignal.prototype, 'reason', originalDesc);
+}