Skip to content

Commit dd451f3

Browse files
committed
chore: use guarded for-in
1 parent 9e44329 commit dd451f3

52 files changed

Lines changed: 199 additions & 57 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/nasty-walls-tap.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@smithy/undici-http-handler": patch
3+
"@smithy/node-http-handler": patch
4+
"@smithy/server-common": patch
5+
"@smithy/core": patch
6+
---
7+
8+
switch for-in loops to guarded

.oxlintrc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"rules": {
1111
"@typescript-eslint/consistent-type-imports": "error",
1212
"@typescript-eslint/no-import-type-side-effects": "error",
13+
"guard-for-in": "error",
1314
"no-sparse-arrays": "off",
1415
"no-unused-vars": ["error", { "args": "none", "caughtErrorsIgnorePattern": "^ignored", "varsIgnorePattern": "^_" }],
1516
"unicorn/no-new-array": "off",

api-snapshot/api.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
"getRetryConfiguration": "function",
133133
"getSmithyContext": "function",
134134
"getValueFromTextNode": "function",
135+
"hasOwn": "function",
135136
"invalidFunction": "function",
136137
"invalidProvider": "function",
137138
"isSerializableHeaderValue": "function",
@@ -543,6 +544,7 @@
543544
},
544545
"@smithy/core/transport": {
545546
"getSmithyContext": "function",
547+
"hasOwn": "function",
546548
"HttpRequest": "function",
547549
"HttpResponse": "function",
548550
"IHttpRequest": "type(interface)",

packages/core/planning/checksums.md

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,57 @@
22

33
Platform: Node.js v22.22.2 (linux x64)
44

5-
Date: 2026-06-24T17:04:04.733Z
5+
Date: 2026-08-14T17:38:50.553Z
66

77
Iterations per size: [10000, 5000, 2000, 200, 20, 5, 3], Warmup: 1s per algo
88

9+
910
## CRC-32
1011

1112
| Size | Crc32Js (JS) | Crc32Node (node:zlib) | @aws-crypto/crc32 |
1213
| ---- | ------------ | --------------------- | ----------------- |
13-
| 32B | 35.3 MB/s | 34.4 MB/s | 28.8 MB/s |
14-
| 256B | 96.0 MB/s | 307.9 MB/s | 77.9 MB/s |
15-
| 1KB | 116.1 MB/s | 1.31 GB/s | 90.4 MB/s |
16-
| 64KB | 121.0 MB/s | 4.52 GB/s | 101.4 MB/s |
17-
| 1MB | 121.2 MB/s | 4.76 GB/s | 100.8 MB/s |
18-
| 10MB | 121.2 MB/s | 4.76 GB/s | 100.3 MB/s |
19-
| 50MB | 121.2 MB/s | 4.74 GB/s | 100.9 MB/s |
14+
| 32B | 34.0 MB/s | 30.8 MB/s | 29.1 MB/s |
15+
| 256B | 95.2 MB/s | 306.5 MB/s | 77.5 MB/s |
16+
| 1KB | 113.7 MB/s | 1.19 GB/s | 91.0 MB/s |
17+
| 64KB | 121.0 MB/s | 4.53 GB/s | 98.7 MB/s |
18+
| 1MB | 121.2 MB/s | 4.74 GB/s | 99.6 MB/s |
19+
| 10MB | 121.2 MB/s | 4.76 GB/s | 99.4 MB/s |
20+
| 50MB | 121.2 MB/s | 4.73 GB/s | 99.3 MB/s |
2021

2122
## SHA-256 (hash)
2223

2324
| Size | Sha256Js (JS) | Sha256Node (node:crypto) | @aws-crypto/sha256-js |
2425
| ---- | ------------- | ------------------------ | --------------------- |
25-
| 32B | 9.4 MB/s | 11.5 MB/s | 5.2 MB/s |
26-
| 256B | 49.0 MB/s | 71.8 MB/s | 35.0 MB/s |
27-
| 1KB | 92.4 MB/s | 211.5 MB/s | 69.8 MB/s |
28-
| 64KB | 116.4 MB/s | 1.58 GB/s | 99.9 MB/s |
29-
| 1MB | 118.8 MB/s | 1.69 GB/s | 100.4 MB/s |
30-
| 10MB | 118.9 MB/s | 1.70 GB/s | 100.6 MB/s |
31-
| 50MB | 118.7 MB/s | 1.70 GB/s | 100.6 MB/s |
26+
| 32B | 9.8 MB/s | 11.2 MB/s | 5.1 MB/s |
27+
| 256B | 49.7 MB/s | 68.7 MB/s | 38.2 MB/s |
28+
| 1KB | 94.2 MB/s | 247.2 MB/s | 73.5 MB/s |
29+
| 64KB | 117.8 MB/s | 1.55 GB/s | 99.8 MB/s |
30+
| 1MB | 118.5 MB/s | 1.69 GB/s | 100.4 MB/s |
31+
| 10MB | 118.7 MB/s | 1.70 GB/s | 100.6 MB/s |
32+
| 50MB | 118.4 MB/s | 1.70 GB/s | 100.6 MB/s |
3233

3334
## SHA-256 (HMAC)
3435

3536
| Size | Sha256Js (JS) | Sha256Node (node:crypto) | @aws-crypto/sha256-js |
3637
| ---- | ------------- | ------------------------ | --------------------- |
37-
| 32B | 3.0 MB/s | 10.6 MB/s | 2.7 MB/s |
38-
| 256B | 20.2 MB/s | 76.7 MB/s | 20.0 MB/s |
39-
| 1KB | 60.4 MB/s | 344.0 MB/s | 55.3 MB/s |
40-
| 64KB | 115.9 MB/s | 1.59 GB/s | 99.6 MB/s |
41-
| 1MB | 118.5 MB/s | 1.69 GB/s | 100.4 MB/s |
42-
| 10MB | 119.0 MB/s | 1.70 GB/s | 100.2 MB/s |
43-
| 50MB | 115.4 MB/s | 1.70 GB/s | 100.6 MB/s |
38+
| 32B | 3.0 MB/s | 10.6 MB/s | 2.8 MB/s |
39+
| 256B | 20.7 MB/s | 78.8 MB/s | 20.6 MB/s |
40+
| 1KB | 61.8 MB/s | 321.8 MB/s | 56.0 MB/s |
41+
| 64KB | 117.3 MB/s | 1.60 GB/s | 99.5 MB/s |
42+
| 1MB | 118.5 MB/s | 1.68 GB/s | 100.4 MB/s |
43+
| 10MB | 118.8 MB/s | 1.70 GB/s | 100.5 MB/s |
44+
| 50MB | 118.8 MB/s | 1.70 GB/s | 100.6 MB/s |
4445

4546
## MD5
4647

4748
Md5Js vs old @smithy/md5-js (unrolled rounds): 0.9x (32B), 2.2x (256B), 2.2x (1KB), 2.1x (64KB), 2.1x (1MB)
4849

4950
| Size | Md5Js (JS) | Md5Node (node:crypto) |
5051
| ---- | ---------- | --------------------- |
51-
| 32B | 10.9 MB/s | 13.3 MB/s |
52-
| 256B | 58.4 MB/s | 87.6 MB/s |
53-
| 1KB | 114.3 MB/s | 261.1 MB/s |
54-
| 64KB | 142.7 MB/s | 756.4 MB/s |
55-
| 1MB | 143.4 MB/s | 775.8 MB/s |
52+
| 32B | 11.1 MB/s | 13.3 MB/s |
53+
| 256B | 58.5 MB/s | 89.6 MB/s |
54+
| 1KB | 114.1 MB/s | 260.6 MB/s |
55+
| 64KB | 142.6 MB/s | 758.0 MB/s |
56+
| 1MB | 143.5 MB/s | 775.4 MB/s |
5657
| 10MB | 143.6 MB/s | 777.4 MB/s |
57-
| 50MB | 143.3 MB/s | 777.6 MB/s |
58+
| 50MB | 143.1 MB/s | 777.8 MB/s |

packages/core/src/legacy-root-exports/util-identity-and-auth/DefaultIdentityProviderConfig.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { hasOwn } from "@smithy/core/transport";
12
import type { HttpAuthSchemeId, Identity, IdentityProvider, IdentityProviderConfig } from "@smithy/types";
23

34
/**
@@ -14,6 +15,7 @@ export class DefaultIdentityProviderConfig implements IdentityProviderConfig {
1415
*/
1516
constructor(config: Record<HttpAuthSchemeId, IdentityProvider<Identity> | undefined>) {
1617
for (const key in config) {
18+
if (!hasOwn(config, key)) continue;
1719
const value = config[key];
1820
if (value !== undefined) {
1921
this.authSchemes.set(key, value);

packages/core/src/submodules/cbor/codec-v1/CborShapeDeserializer.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { hasOwn } from "@smithy/core/transport";
12
import { SerdeContext } from "@smithy/core/protocols";
23
import { NormalizedSchema } from "@smithy/core/schema";
34
import { NumericValue, _parseEpochTimestamp, fromBase64 } from "@smithy/core/serde";
@@ -80,6 +81,7 @@ export class CborShapeDeserializer extends SerdeContext implements ShapeDeserial
8081
const targetSchema = ns.getValueSchema();
8182

8283
for (const key in value) {
84+
if (!hasOwn(value, key)) continue;
8385
const itemValue = this.readValue(targetSchema, value[key]);
8486
newObject[key] = itemValue;
8587
}
@@ -89,6 +91,7 @@ export class CborShapeDeserializer extends SerdeContext implements ShapeDeserial
8991
if (isUnion) {
9092
keys = new Set<string>();
9193
for (const k in value) {
94+
if (!hasOwn(value, k)) continue;
9295
if (k !== "__type") {
9396
keys.add(k);
9497
}
@@ -105,6 +108,7 @@ export class CborShapeDeserializer extends SerdeContext implements ShapeDeserial
105108
if (isUnion && keys?.size === 1) {
106109
let newObjectEmpty = true;
107110
for (const _ in newObject) {
111+
if (!hasOwn(newObject, _)) continue;
108112
newObjectEmpty = false;
109113
break;
110114
}
@@ -116,6 +120,7 @@ export class CborShapeDeserializer extends SerdeContext implements ShapeDeserial
116120
// This if-block is for backwards compatibility support and should not be copied
117121
// to other implementations.
118122
for (const k in value) {
123+
if (!hasOwn(value, k)) continue;
119124
if (!(k in newObject)) {
120125
// we have no type information, so copy as-is from CBOR-derived object.
121126
newObject[k] = value[k];

packages/core/src/submodules/cbor/codec-v1/CborShapeSerializer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { hasOwn } from "@smithy/core/transport";
12
import { SerdeContext } from "@smithy/core/protocols";
23
import { NormalizedSchema } from "@smithy/core/schema";
34
import { _parseEpochTimestamp, fromBase64, generateIdempotencyToken } from "@smithy/core/serde";
@@ -66,6 +67,7 @@ export class CborShapeSerializer extends SerdeContext implements ShapeSerializer
6667
if (ns.isMapSchema()) {
6768
const sparse = !!ns.getMergedTraits().sparse;
6869
for (const key in sourceObject) {
70+
if (!hasOwn(sourceObject, key)) continue;
6971
const value = this.serialize(ns.getValueSchema(), sourceObject[key]);
7072
if (value != null || sparse) {
7173
newObject[key] = value;
@@ -86,6 +88,7 @@ export class CborShapeSerializer extends SerdeContext implements ShapeSerializer
8688
// This if-block is for backwards compatibility support and should not be copied
8789
// to other implementations.
8890
for (const k in sourceObject) {
91+
if (!hasOwn(sourceObject, k)) continue;
8992
if (!(k in newObject)) {
9093
// we have no type information, so serialize with Document rules.
9194
newObject[k] = this.serialize(15 satisfies DocumentSchema, sourceObject[k]);
@@ -102,6 +105,7 @@ export class CborShapeSerializer extends SerdeContext implements ShapeSerializer
102105
return newArray;
103106
}
104107
for (const key in sourceObject) {
108+
if (!hasOwn(sourceObject, key)) continue;
105109
newObject[key] = this.serialize(ns.getValueSchema(), sourceObject[key]);
106110
}
107111
} else if (ns.isBigDecimalSchema()) {

packages/core/src/submodules/cbor/codec-v2/CborShapeDeserializer2.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { hasOwn } from "@smithy/core/transport";
12
import { SerdeContext } from "@smithy/core/protocols";
23
import { NormalizedSchema } from "@smithy/core/schema";
34
import { NumericValue, _parseEpochTimestamp, nv } from "@smithy/core/serde";
@@ -173,6 +174,7 @@ function readStruct(ns: NormalizedSchema, count: number, startPos: number): any
173174
if (isUnion) {
174175
let resultEmpty = true;
175176
for (const _ in result) {
177+
if (!hasOwn(result, _)) continue;
176178
resultEmpty = false;
177179
break;
178180
}
@@ -348,6 +350,7 @@ function readMapIndefinite(ns: NormalizedSchema): any {
348350
if (isUnion) {
349351
let resultEmpty = true;
350352
for (const _ in result) {
353+
if (!hasOwn(result, _)) continue;
351354
resultEmpty = false;
352355
break;
353356
}
@@ -694,6 +697,7 @@ function transformObject(ns: NormalizedSchema, value: any): any {
694697
if (ns.isMapSchema()) {
695698
const targetSchema = ns.getValueSchema();
696699
for (const key in value) {
700+
if (!hasOwn(value, key)) continue;
697701
newObject[key] = transformObject(targetSchema, value[key]);
698702
}
699703
} else if (ns.isStructSchema()) {
@@ -702,6 +706,7 @@ function transformObject(ns: NormalizedSchema, value: any): any {
702706
if (isUnion) {
703707
keys = new Set<string>();
704708
for (const k in value) {
709+
if (!hasOwn(value, k)) continue;
705710
if (k !== "__type") {
706711
keys.add(k);
707712
}
@@ -718,6 +723,7 @@ function transformObject(ns: NormalizedSchema, value: any): any {
718723
if (isUnion && keys?.size === 1) {
719724
let newObjectEmpty = true;
720725
for (const _ in newObject) {
726+
if (!hasOwn(newObject, _)) continue;
721727
newObjectEmpty = false;
722728
break;
723729
}
@@ -727,6 +733,7 @@ function transformObject(ns: NormalizedSchema, value: any): any {
727733
}
728734
} else if (typeof value.__type === "string") {
729735
for (const k in value) {
736+
if (!hasOwn(value, k)) continue;
730737
if (!(k in newObject)) {
731738
newObject[k] = value[k];
732739
}

packages/core/src/submodules/cbor/codec-v2/CborShapeSerializer2.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { hasOwn } from "@smithy/core/transport";
12
import { SerdeContext } from "@smithy/core/protocols";
23
import { NormalizedSchema } from "@smithy/core/schema";
34
import { NumericValue, fromBase64, generateIdempotencyToken } from "@smithy/core/serde";
@@ -353,6 +354,7 @@ function writeStruct(ns: NormalizedSchema, value: Record<string, unknown>, serde
353354

354355
if (typeof value.__type === "string") {
355356
for (const k in value) {
357+
if (!hasOwn(value, k)) continue;
356358
if (!memberNames.includes(k)) {
357359
writeString(k);
358360
writeUntypedValue(value[k]);
@@ -419,6 +421,7 @@ function writeMap(ns: NormalizedSchema, value: Record<string, unknown>, isDocume
419421

420422
const keys: string[] = [];
421423
for (const k in value) {
424+
if (!hasOwn(value, k)) continue;
422425
const v = value[k];
423426
if (isDocument ? v !== undefined : v != null || sparse) {
424427
keys.push(k);

packages/core/src/submodules/cbor/parseCborBody.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { hasOwn } from "@smithy/core/transport";
12
import { HttpRequest as __HttpRequest, collectBody } from "@smithy/core/protocols";
23
import { calculateBodyLength } from "@smithy/core/serde";
34
import type {
@@ -75,6 +76,7 @@ export const loadSmithyRpcV2CborErrorCode = (output: HttpResponse, data: any): s
7576

7677
let codeKey: string | undefined;
7778
for (const key in data) {
79+
if (!hasOwn(data, key)) continue;
7880
if (key.toLowerCase() === "code") {
7981
codeKey = key;
8082
break;
@@ -122,6 +124,7 @@ export const buildHttpRpcRequest = async (
122124
}
123125
if (endpoint.headers) {
124126
for (const name in endpoint.headers) {
127+
if (!hasOwn(endpoint.headers, name)) continue;
125128
contents.headers[name] = endpoint.headers[name];
126129
}
127130
}

0 commit comments

Comments
 (0)