-
Notifications
You must be signed in to change notification settings - Fork 653
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
dynamodb: StringSet and StringSet decoders call unmarshaller incorrectly #2895
Comments
Hi @AnatolyRugalev , Thanks for the report. Indeed looks like a bug. We will have someone review your PR. All the best, |
@AnatolyRugalev Is there a reason you have a marshaler implemented in this case for the string alias? All it's doing is taking the string attribute value and setting it to the receiver. The reported bug is totally valid, but if you removed the unmarshaller implementation you wouldn't hit the bad code path here. We're not opposed to taking your patch in #2896 but it's not something we can change by default - it would have to be opt-in. It's entirely possible to write an unmarshaler that responds to this incorrect behavior (suppose your unmarshal implementation had an additional case for |
Hey @lucix-aws , Unfortunately, that unmarshaller is not possible to implement. Unmarshal function's receiver type is Thanks for looking into this.
Just to clarify, I can agree that it is technically possible, but it's not really feasible in a real code base. Let's assume that someone has implemented a workaround and assigns var unmarshaledStringSet []myType
func (m *myType) UnmarshalDynamoDBAttributeValue(av types.AttributeValue) error {
switch v := av.(type) {
case *types.AttributeValueMemberSS:
unmarhsaledStringSet = valueFromStringSet(v)
return nil
default:
return errors.New("unexpected type")
}
} That would mean that it will be impossible to call this unmarshaler multiple times without resetting the state. If we make package level var a slice, then you won't be able to associate which set belongs to which attribute path, since attribute path is not accessible from within the unmarshaler. This makes me to believe that the more plausible workaround is to just not to use unmarshaler for SS values and rely on pure While technically it's a breaking change, I would argue that this has never worked before, and we can safely fix it without breaking any contracts. |
This is just not true though. Whether or not it worked before depends entirely on the Unmarshal implementation. Something like your example, or even something like this, type myType string
type doc struct {
Items []myType `dynamodbav:"items,stringset"`
}
func (m *myType) UnmarshalDynamoDBAttributeValue(av types.AttributeValue) error {
switch v := av.(type) {
case *types.AttributeValueMemberS:
*m = myType(v.Value)
return nil
case *types.AttributeValueMemberSS:
// this could literally be anything, it's just an example
*m = myType(strings.Join(v.Value, ","))
return nil
default:
return errors.New("unexpected type")
}
} regardless of whether we consider them "valid" or "sensible" could absolutely exist in the wild. The customer could have either stumbled across this bug and tried to work around it, or they could literally be unaware that it's affecting them.
I think we're undermining the possibility of this being depended on in general. We're not taking that risk with customer data from a tier-zero AWS service in an SDK used by tens of thousands of calling applications. Again, your patch is fine. But it has to be opt-in. If not, we'll need to close the PR. |
Alright, I will add a flag then |
FYI, the pull request has been updated: #2896 |
Acknowledgements
go get -u github.com/aws/aws-sdk-go-v2/...
)Describe the bug
When unmarshaling StringSet or NumberSet values via
attributevalue.Unmarshal
, unmarshaller interface receives the whole set instead of individual slice items.Unmarshaler is called here: https://github.com/aws/aws-sdk-go-v2/blob/main/feature/dynamodb/attributevalue/decode.go#L807
This issue is present in both
dynamodb/attributevalue
anddynamodbstreams/attributevalue
Regression Issue
Expected Behavior
Unmarshaler should receive individual set items
Current Behavior
Unmarshaler receives the whole set
Reproduction Steps
Possible Solution
Additional Information/Context
No response
AWS Go SDK V2 Module Versions Used
Compiler and Version used
go version go1.23.2 darwin/arm64
Operating System and version
MacOS
The text was updated successfully, but these errors were encountered: