@@ -47,6 +47,7 @@ func decode(encoded string) (string, error) {
47
47
}
48
48
}
49
49
i , n , bias := int32 (0 ), initialN , initialBias
50
+ overflow := false
50
51
for pos < len (encoded ) {
51
52
oldI , w := i , int32 (1 )
52
53
for k := base ; ; k += base {
@@ -58,29 +59,32 @@ func decode(encoded string) (string, error) {
58
59
return "" , punyError (encoded )
59
60
}
60
61
pos ++
61
- i += digit * w
62
- if i < 0 {
62
+ i , overflow = madd ( i , digit , w )
63
+ if overflow {
63
64
return "" , punyError (encoded )
64
65
}
65
66
t := k - bias
66
- if t < tmin {
67
+ if k <= bias {
67
68
t = tmin
68
- } else if t > tmax {
69
+ } else if k >= bias + tmax {
69
70
t = tmax
70
71
}
71
72
if digit < t {
72
73
break
73
74
}
74
- w *= base - t
75
- if w >= math . MaxInt32 / base {
75
+ w , overflow = madd ( 0 , w , base - t )
76
+ if overflow {
76
77
return "" , punyError (encoded )
77
78
}
78
79
}
80
+ if len (output ) >= 1024 {
81
+ return "" , punyError (encoded )
82
+ }
79
83
x := int32 (len (output ) + 1 )
80
84
bias = adapt (i - oldI , x , oldI == 0 )
81
85
n += i / x
82
86
i %= x
83
- if n > utf8 . MaxRune || len ( output ) >= 1024 {
87
+ if n < 0 || n > utf8 . MaxRune {
84
88
return "" , punyError (encoded )
85
89
}
86
90
output = append (output , 0 )
@@ -113,15 +117,16 @@ func encode(prefix, s string) (string, error) {
113
117
if b > 0 {
114
118
output = append (output , '-' )
115
119
}
120
+ overflow := false
116
121
for remaining != 0 {
117
122
m := int32 (0x7fffffff )
118
123
for _ , r := range s {
119
124
if m > r && r >= n {
120
125
m = r
121
126
}
122
127
}
123
- delta += ( m - n ) * ( h + 1 )
124
- if delta < 0 {
128
+ delta , overflow = madd ( delta , m - n , h + 1 )
129
+ if overflow {
125
130
return "" , punyError (s )
126
131
}
127
132
n = m
@@ -139,9 +144,9 @@ func encode(prefix, s string) (string, error) {
139
144
q := delta
140
145
for k := base ; ; k += base {
141
146
t := k - bias
142
- if t < tmin {
147
+ if k <= bias {
143
148
t = tmin
144
- } else if t > tmax {
149
+ } else if k >= bias + tmax {
145
150
t = tmax
146
151
}
147
152
if q < t {
@@ -162,6 +167,15 @@ func encode(prefix, s string) (string, error) {
162
167
return string (output ), nil
163
168
}
164
169
170
+ // madd computes a + (b * c), detecting overflow.
171
+ func madd (a , b , c int32 ) (next int32 , overflow bool ) {
172
+ p := int64 (b ) * int64 (c )
173
+ if p > math .MaxInt32 - int64 (a ) {
174
+ return 0 , true
175
+ }
176
+ return a + int32 (p ), false
177
+ }
178
+
165
179
func decodeDigit (x byte ) (digit int32 , ok bool ) {
166
180
switch {
167
181
case '0' <= x && x <= '9' :
0 commit comments