-
Notifications
You must be signed in to change notification settings - Fork 218
Fixes encoding of circular referenced object / complex object #1525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
74d205c
2f92f08
1cd966d
1922293
53e5b66
c68b120
b5f375d
37e41ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -404,12 +404,14 @@ const LONG_TYPE = "type.googleapis.com/google.protobuf.Int64Value"; | |||||||||||||||||||||||||||||||||||||
| /** @hidden */ | ||||||||||||||||||||||||||||||||||||||
| const UNSIGNED_LONG_TYPE = "type.googleapis.com/google.protobuf.UInt64Value"; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| /** @hidden */ | ||||||||||||||||||||||||||||||||||||||
| const SELF_REFERENCE_WEAKSET = new WeakSet<object|((...args:any[])=>any)>(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
| const SELF_REFERENCE_WEAKSET = new WeakSet<object|((...args:any[])=>any)>(); | |
| const SELF_REFERENCE_WEAKSET = new WeakSet(); |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a module-level WeakSet for tracking circular references creates a potential issue in concurrent request scenarios. If multiple encode calls execute simultaneously (common in serverless environments), they will share the same WeakSet, potentially causing false positives where an object from one request is detected as circular in another. The WeakSet should be passed as a parameter through recursive calls or use a different approach for circular reference detection.
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing spaces around operators. Should be if (!isFunctionOrObject(data) || SELF_REFERENCE_WEAKSET.has(data)) for consistency with project style.
| if(!isFunctionOrObject(data)||SELF_REFERENCE_WEAKSET.has(data)) { | |
| if (!isFunctionOrObject(data) || SELF_REFERENCE_WEAKSET.has(data)) { |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic is inverted. The condition !isFunctionOrObject(data) returns true when data is NOT an object/function (which is correct to throw), but combining it with || SELF_REFERENCE_WEAKSET.has(data) means it will also throw when a circular reference is detected AND when data is not an object. This breaks the existing test at line 967 which expects functions to encode as empty objects {}. The condition should be split: handle non-object/function first, then check for circular references separately.
| if(!isFunctionOrObject(data)||SELF_REFERENCE_WEAKSET.has(data)) { | |
| logger.error("Data cannot be encoded in JSON.", data); | |
| throw new Error(`Data cannot be encoded in JSON: ${data}`); | |
| } | |
| if (!isFunctionOrObject(data)) { | |
| logger.error("Data cannot be encoded in JSON.", data); | |
| throw new Error(`Data cannot be encoded in JSON: ${data}`); | |
| } | |
| if (SELF_REFERENCE_WEAKSET.has(data)) { | |
| logger.error("Data cannot be encoded in JSON (circular reference detected).", data); | |
| throw new Error(`Data cannot be encoded in JSON (circular reference detected): ${data}`); | |
| } |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type predicate object|((...args:any[])=>any) is redundant. Since functions are objects in JavaScript, the predicate should be data is object. Additionally, this function could be simplified to a single line: return typeof data === 'object' || typeof data === 'function';
| function isFunctionOrObject(data: unknown): data is object|((...args:any[])=>any) { | |
| const isObjectOrFunction = typeof data === "object" || typeof data === "function"; | |
| if (!isObjectOrFunction) { | |
| // If we got this far, the data is not encodable. | |
| return false; | |
| } | |
| return true; | |
| function isFunctionOrObject(data: unknown): data is object { | |
| return typeof data === "object" || typeof data === "function"; |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is unnecessarily complex. The comment 'If we got this far, the data is not encodable' is misleading since the function just checks if data is an object or function, not whether it's encodable. The entire function can be simplified to: return typeof data === 'object' || typeof data === 'function';
| const isObjectOrFunction = typeof data === "object" || typeof data === "function"; | |
| if (!isObjectOrFunction) { | |
| // If we got this far, the data is not encodable. | |
| return false; | |
| } | |
| return true; | |
| return typeof data === "object" || typeof data === "function"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing spaces around the arrow function. Should be
() => https.encode(testObject)for consistency with project style (see line 968).