@@ -150,22 +150,24 @@ int color_parse(const char *value, char *dst)
150
150
* already have the ANSI escape code in it. "out" should have enough
151
151
* space in it to fit any color.
152
152
*/
153
- static char * color_output (char * out , const struct color * c , char type )
153
+ static char * color_output (char * out , int len , const struct color * c , char type )
154
154
{
155
155
switch (c -> type ) {
156
156
case COLOR_UNSPECIFIED :
157
157
case COLOR_NORMAL :
158
158
break ;
159
159
case COLOR_ANSI :
160
+ if (len < 2 )
161
+ die ("BUG: color parsing ran out of space" );
160
162
* out ++ = type ;
161
163
* out ++ = '0' + c -> value ;
162
164
break ;
163
165
case COLOR_256 :
164
- out += sprintf (out , "%c8;5;%d" , type , c -> value );
166
+ out += xsnprintf (out , len , "%c8;5;%d" , type , c -> value );
165
167
break ;
166
168
case COLOR_RGB :
167
- out += sprintf (out , "%c8;2;%d;%d;%d" , type ,
168
- c -> red , c -> green , c -> blue );
169
+ out += xsnprintf (out , len , "%c8;2;%d;%d;%d" , type ,
170
+ c -> red , c -> green , c -> blue );
169
171
break ;
170
172
}
171
173
return out ;
@@ -180,12 +182,13 @@ int color_parse_mem(const char *value, int value_len, char *dst)
180
182
{
181
183
const char * ptr = value ;
182
184
int len = value_len ;
185
+ char * end = dst + COLOR_MAXLEN ;
183
186
unsigned int attr = 0 ;
184
187
struct color fg = { COLOR_UNSPECIFIED };
185
188
struct color bg = { COLOR_UNSPECIFIED };
186
189
187
190
if (!strncasecmp (value , "reset" , len )) {
188
- strcpy ( dst , GIT_COLOR_RESET );
191
+ xsnprintf ( dst , end - dst , GIT_COLOR_RESET );
189
192
return 0 ;
190
193
}
191
194
@@ -224,40 +227,48 @@ int color_parse_mem(const char *value, int value_len, char *dst)
224
227
goto bad ;
225
228
}
226
229
230
+ #undef OUT
231
+ #define OUT (x ) do { \
232
+ if (dst == end) \
233
+ die("BUG: color parsing ran out of space"); \
234
+ *dst++ = (x); \
235
+ } while(0)
236
+
227
237
if (attr || !color_empty (& fg ) || !color_empty (& bg )) {
228
238
int sep = 0 ;
229
239
int i ;
230
240
231
- * dst ++ = '\033' ;
232
- * dst ++ = '[' ;
241
+ OUT ( '\033' ) ;
242
+ OUT ( '[' ) ;
233
243
234
244
for (i = 0 ; attr ; i ++ ) {
235
245
unsigned bit = (1 << i );
236
246
if (!(attr & bit ))
237
247
continue ;
238
248
attr &= ~bit ;
239
249
if (sep ++ )
240
- * dst ++ = ';' ;
241
- dst += sprintf ( dst , "%d" , i );
250
+ OUT ( ';' ) ;
251
+ dst += xsnprintf ( dst , end - dst , "%d" , i );
242
252
}
243
253
if (!color_empty (& fg )) {
244
254
if (sep ++ )
245
- * dst ++ = ';' ;
255
+ OUT ( ';' ) ;
246
256
/* foreground colors are all in the 3x range */
247
- dst = color_output (dst , & fg , '3' );
257
+ dst = color_output (dst , end - dst , & fg , '3' );
248
258
}
249
259
if (!color_empty (& bg )) {
250
260
if (sep ++ )
251
- * dst ++ = ';' ;
261
+ OUT ( ';' ) ;
252
262
/* background colors are all in the 4x range */
253
- dst = color_output (dst , & bg , '4' );
263
+ dst = color_output (dst , end - dst , & bg , '4' );
254
264
}
255
- * dst ++ = 'm' ;
265
+ OUT ( 'm' ) ;
256
266
}
257
- * dst = 0 ;
267
+ OUT ( 0 ) ;
258
268
return 0 ;
259
269
bad :
260
270
return error (_ ("invalid color value: %.*s" ), value_len , value );
271
+ #undef OUT
261
272
}
262
273
263
274
int git_config_colorbool (const char * var , const char * value )
0 commit comments