@@ -35,23 +35,36 @@ func pad(buf []byte, n int) []byte {
35
35
func unpad (buf []byte , n int ) ([]byte , error ) {
36
36
lbuf := len (buf )
37
37
rem := lbuf % n
38
+
39
+ // First, `buf` must be a multiple of `n`
38
40
if rem != 0 {
39
41
return nil , errors .Errorf ("input buffer must be multiple of block size %d" , n )
40
42
}
41
43
42
- count := 0
44
+ // Find the last byte, which is the encoded padding
45
+ // i.e. 0x1 == 1 byte worth of padding
43
46
last := buf [lbuf - 1 ]
44
- for i := lbuf - 1 ; i >= 0 ; i -- {
45
- if buf [i ] != last {
46
- break
47
- }
48
- count ++
47
+
48
+ // This is the number of padding bytes that we expect
49
+ expected := int (last )
50
+
51
+ if expected == 0 || /* we _have_ to have padding here. therefore, 0x0 is not an option */
52
+ expected > n || /* we also must make sure that we don't go over the block size (n) */
53
+ expected > lbuf /* finally, it can't be more than the buffer itself. unlikely, but could happen */ {
54
+ return nil , fmt .Errorf (`invalid padding byte at the end of buffer` )
49
55
}
50
- if count != int (last ) {
51
- return nil , errors .New ("invalid padding" )
56
+
57
+ // start i = 1 because we have already established that expected == int(last) where
58
+ // last = buf[lbuf-1].
59
+ //
60
+ // we also don't check against lbuf-i in range, because we have established expected <= lbuf
61
+ for i := 1 ; i < expected ; i ++ {
62
+ if buf [lbuf - i ] != last {
63
+ return nil , errors .New (`invalid padding` )
64
+ }
52
65
}
53
66
54
- return buf [:lbuf - int ( last ) ], nil
67
+ return buf [:lbuf - expected ], nil
55
68
}
56
69
57
70
type Hmac struct {
0 commit comments