-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
fix(integ-tests): Uint8Arrays are not decoded properly #27009
Conversation
…sing the string is an object
|
||
if (parsed != null && !Array.isArray(parsed) && typeof parsed === 'object') { | ||
const entries = Object.entries(parsed); | ||
if (isByteArray(entries)) { |
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.
But what if the payload is a dictionary that looks like a stringified bytearray, but is actually supposed to be a normal dictionary?
I agree it might be a little edgy, but can we think of a different solution that considers it? Like adding a marker property when we encode, so we can use it when we decode?
@mrgrain remember this? can you think of another way?
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.
I don't even understand how we end up here. Where is that Uint8Array
coming from, and how did it end up JSON.stringify()
ed here?
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.
It is being passed directly by the user.
const kinesisStream: IStream = new Stream(stack, "TestKinesisStream");
const buf = Buffer.from(JSON.stringify({ name: "world" }));
const data = new Uint8Array(
buf.buffer,
buf.byteOffset,
buf.byteLength / Uint8Array.BYTES_PER_ELEMENT
);
testCase.assertions.awsApiCall("Kinesis", "putRecord", {
StreamName: kinesisStream.streamName,
Data: data,
PartitionKey: "testKey",
});
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.
Yeah, there is a reason why untyped arguments that go over the network should really be JSON strings 🙈
I wonder if this is even a SDKv3 bug. I know we changed the handling here, but this might have not worked before (but I don't know).
I'll guess we have to put a marker on it if we want to support it. Also should probably base64 encode it during transit.
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.
Yeah a Uint8Array
cannot be expected to be sent over the wire just like that.
Either:
- We reject the value, but allow the use case by making the equality testing a bit smarter in the assertions library -- perhaps we can test the equality of a Uint8Array to a string (assuming utf-8 encoding), or an array of numbers.
- Either that, or we marshal the
Uint8Array
explicitly over the wire with a type tag, and reconstruct it on the other end.
Honestly, I'm feeling most for the first solution. Morally, what we are trying to do is test equality of the buffer to a certain string. The fact that we need to encode/decode that string/byte array could be an implementation detail that that the assertions module just takes care of.
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.
See my last comment
* signals to the decoder that "foo" should be handled separately | ||
* and treated as an array of bytes. | ||
*/ | ||
readonly specialTypes?: Record<string, string>; |
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 solution of marking certain parameters as having a different type cannot be applied recursively (or at least not conveniently).
Can we not do an object with a type tag, that we can apply recursively?
encode({
string: 'string',
obj: { field: 'value' },
weirdarray: new Uint8Array([1, 2, 3]),
})
// =>
{
string: 'string',
obj: { field: 'value' },
weirdarray: {
'$type': 'ArrayBufferView',
elements: [1, 2, 3],
},
}
EDIT: or, as you're doing today:
{
'$type': 'ArrayBufferView',
bytes: '\x01\x02\x03',
}
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
…ry (#27092) #27009 introduced support for `Uint8Array` if users want to send data with the same types as those declared in the SDK v3 API. But existing tests, that use strings, will break. Apply type coercion when necessary. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
AWS SDK v3 has changed some data types to Uint8Array. If a value of this type was provided by the user, it would not be decoded properly back to a Uint8Array before making the call. Recognize when there is an encoded Uint8Array and decode it back properly. Closes #26798. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
…ry (#27092) #27009 introduced support for `Uint8Array` if users want to send data with the same types as those declared in the SDK v3 API. But existing tests, that use strings, will break. Apply type coercion when necessary. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
AWS SDK v3 has changed some data types to Uint8Array. If a value of this type was provided by the user, it would not be decoded properly back to a Uint8Array before making the call.
Recognize when there is an encoded Uint8Array and decode it back properly.
Closes #26798.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license