summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--multipart/formfile.ts7
-rw-r--r--multipart/formfile_test.ts12
-rw-r--r--util/has_own_property.ts30
-rw-r--r--ws/mod.ts3
4 files changed, 46 insertions, 6 deletions
diff --git a/multipart/formfile.ts b/multipart/formfile.ts
index 592f4e529..a0e721a15 100644
--- a/multipart/formfile.ts
+++ b/multipart/formfile.ts
@@ -1,4 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+import { hasOwnProperty } from "../util/has_own_property.ts";
/** FormFile object */
export interface FormFile {
@@ -19,9 +20,5 @@ export interface FormFile {
/** Type guard for FormFile */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isFormFile(x: any): x is FormFile {
- return (
- typeof x === "object" &&
- x.hasOwnProperty("filename") &&
- x.hasOwnProperty("type")
- );
+ return hasOwnProperty(x, "filename") && hasOwnProperty(x, "type");
}
diff --git a/multipart/formfile_test.ts b/multipart/formfile_test.ts
index 63509fc9d..52dd3addd 100644
--- a/multipart/formfile_test.ts
+++ b/multipart/formfile_test.ts
@@ -18,3 +18,15 @@ test(function multipartIsFormFile(): void {
false
);
});
+
+test(function isFormFileShouldNotThrow(): void {
+ assertEquals(
+ isFormFile({
+ filename: "foo",
+ type: "application/json",
+ hasOwnProperty: "bar"
+ }),
+ true
+ );
+ assertEquals(isFormFile(Object.create(null)), false);
+});
diff --git a/util/has_own_property.ts b/util/has_own_property.ts
new file mode 100644
index 000000000..707d951d3
--- /dev/null
+++ b/util/has_own_property.ts
@@ -0,0 +1,30 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+
+/**
+ * Determines whether an object has a property with the specified name.
+ * Avoid calling prototype builtin `hasOwnProperty` for two reasons:
+ *
+ * 1. `hasOwnProperty` is defined on the object as something else:
+ *
+ * const options = {
+ * ending: 'utf8',
+ * hasOwnProperty: 'foo'
+ * };
+ * options.hasOwnProperty('ending') // throws a TypeError
+ *
+ * 2. The object doesn't inherit from `Object.prototype`:
+ *
+ * const options = Object.create(null);
+ * options.ending = 'utf8';
+ * options.hasOwnProperty('ending'); // throws a TypeError
+ *
+ * @param obj A Object.
+ * @param v A property name.
+ * @see https://eslint.org/docs/rules/no-prototype-builtins
+ */
+export function hasOwnProperty<T>(obj: T, v: PropertyKey): boolean {
+ if (obj == null) {
+ return false;
+ }
+ return Object.prototype.hasOwnProperty.call(obj, v);
+}
diff --git a/ws/mod.ts b/ws/mod.ts
index df8cab01f..b649ef178 100644
--- a/ws/mod.ts
+++ b/ws/mod.ts
@@ -1,6 +1,7 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { decode, encode } from "../strings/mod.ts";
+import { hasOwnProperty } from "../util/has_own_property.ts";
type Conn = Deno.Conn;
type Writer = Deno.Writer;
@@ -34,7 +35,7 @@ export interface WebSocketCloseEvent {
export function isWebSocketCloseEvent(
a: WebSocketEvent
): a is WebSocketCloseEvent {
- return typeof a === "object" && a.hasOwnProperty("code");
+ return hasOwnProperty(a, "code");
}
export type WebSocketPingEvent = ["ping", Uint8Array];