-
Notifications
You must be signed in to change notification settings - Fork 366
fix: enhance marshalUint64 to trim leading zeros and ensure one byte #513
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: enhance marshalUint64 to trim leading zeros and ensure one byte #513
Conversation
…one byte is returned Signed-off-by: wregen <W.Regenczuk@gmail.com>
@soniah can I ask you to look at it? |
What issue does this fix? |
return []byte{0} // Always return at least one byte | ||
} | ||
|
||
if trimmed[0]&0x80 > 0 { |
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.
What is this doing?
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 same functionality is implemented in marshalUint32 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.
Strange, I wonder why it was implemented only for 32-bit.
I’m currently out of office and shortly for now I can mention what I remember
Tommorow I will ask my developer for technical justification of this change and some snmp spec refering to it. With this change my snmp simulator with your library successfully discover my devices (represented by *.snmprec files) |
I think I understand the first part, always returning a single empty byte. But I'm not sure about the second half. |
I asked AI to explain as I cannot repeat exactly my college (I will ask him tommorow to confirm) 🔧 The Issue In helper.go, the unmarshalInt64 implementation had a subtle bug: when decoding a value of zero, it was not returning 0 properly. Instead, due to how length or payload were interpreted, it returned an error or a nil value. The correct behavior—as per ASN.1 BER encoding—is to return 0 when the integer data is exactly zero. ⸻ ✅ What the Fixed Version Does |
I'm pretty sure the second half of this is unnecessary, as the If this is not correct, tests need to be updated in order to prove the change does the correct thing. |
if len(trimmed) == 0 { | ||
return []byte{0} // Always return at least one byte |
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.
We should really add some tests for marshalUint64()
.
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.
by the way thank you for prompt response
I will check tommorow if it works without this part however this won’t be a proof that it won’t break some other scenario. I will ask my college to comment that. By the way … yes, tests are crutial :-) I’m a QA/QC engineer and write a bit some tests software. |
Current implementation did not handle case properly when Counter64 value was 0 or 255(The MSB is negative):
This implementation for 0 returns nil. Problem with arraises in
the len(nil) is 0, but actuall value is sent so length byte is missing: Lets look into 0 and 255 case in new implementation:
Function |
As mentioned earlier, the change works as follows:
|
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 think we are on the right way by fixing this bug, but need to iterate on added comments as we then also improve on stability.
As Ben mentioned we are missing tests.
@@ -331,9 +331,18 @@ func marshalInt32(value int) ([]byte, error) { | |||
func marshalUint64(v interface{}) []byte { |
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.
If we decide to touch this. Lets make clear why this function is here, and how it should work as per spec.
I would prefer to add a comment like this above the function definition.
// marshalUint64 encodes a uint64 according to BER rules (X.690) for SNMP Counter64 values.
// It trims leading zeros and prepends 0x00 if the first byte would otherwise be interpreted as negative.
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 missed to add about 5 pending comments here ... My apologies for that, I'll try to update it within ~ 24h.
My review comments can be fixed in another iteration.
fix: enhance marshalUint64 to trim leading zeros and ensure at least one byte is returned