@@ -300,7 +300,7 @@ format_expand_arg(struct format_context *format, const char *name, const char *e
300
300
const char * value ;
301
301
const char * msgstart = name + STRING_SIZE ("%(prompt" );
302
302
const int msglen = end - msgstart - 1 ;
303
-
303
+ char * tmp ;
304
304
if (end && msglen > 0 && string_format (msgbuf , "%.*s" , msglen , msgstart )) {
305
305
const char * msg = msgbuf ;
306
306
@@ -310,7 +310,9 @@ format_expand_arg(struct format_context *format, const char *name, const char *e
310
310
prompt = msg ;
311
311
}
312
312
313
- value = read_prompt (prompt );
313
+ tmp = argv_format_arg (& argv_env , prompt );
314
+ value = read_prompt (tmp );
315
+ free (tmp );
314
316
if (value == NULL )
315
317
return false;
316
318
return string_format_from (format -> buf , & format -> bufpos , "%s" , value );
@@ -322,6 +324,7 @@ format_expand_arg(struct format_context *format, const char *name, const char *e
322
324
const char * cstart = name + STRING_SIZE ("%(sh" );
323
325
const int clen = end - cstart - 1 ;
324
326
int size ;
327
+ char * tmp ;
325
328
FILE * cp ;
326
329
if (end && clen > 0 && string_format (cbuf , "sh -c '%.*s'" , clen , cstart )) {
327
330
c = cbuf ;
@@ -330,7 +333,9 @@ format_expand_arg(struct format_context *format, const char *name, const char *e
330
333
}
331
334
if (!* c || strlen (c )== 8 )
332
335
return false;
333
- cp = popen (c ,"r" );
336
+ tmp = argv_format_arg (& argv_env , c );
337
+ cp = popen (tmp ,"r" );
338
+ free (tmp );
334
339
size = fread (value ,1 ,SIZEOF_STR - 1 ,cp );
335
340
if (value [0 ]== 0 || size == 0 )
336
341
return false;
@@ -352,6 +357,64 @@ format_expand_arg(struct format_context *format, const char *name, const char *e
352
357
return false;
353
358
}
354
359
360
+ static const char *
361
+ get_closing_brace (const char * input )
362
+ {
363
+ const char * s = input ,* cur , * tmp ;
364
+ int idx ,level = 0 ,pair_idx ;
365
+ int level_to_pos [3000 ]= {[0 ... 2998 ]= -1 , -2 };
366
+ int pos_to_level [256 ]= {[0 ... 254 ]= -1 , -2 };
367
+ int pair_map [3000 ]= {[0 ... 2998 ]= -1 , -2 };
368
+ int final_pairs [3000 ]= {[0 ... 2998 ]= -1 , -2 };
369
+ int first = -1 ;
370
+ while ( (cur = strstr (s ,"(" )), (tmp = strstr (s ,")" )), (cur && cur < tmp ?cur :(cur = tmp ))) {
371
+ s = cur + 1 ;
372
+ idx = cur - input ;
373
+ if ( * cur == '(' ) {
374
+ pos_to_level [idx ]= ++ level ;
375
+ level_to_pos [level ]= idx ;
376
+ } else if ( * cur == ')' ) {
377
+ if ( level > 0 ) {
378
+ pair_idx = level_to_pos [level ];
379
+ pos_to_level [idx ]= level -- ;
380
+ if (input [pair_idx ]== '(' && input [idx ]== ')' ||
381
+ input [pair_idx ]== ')' && input [idx ]== '(' ) {
382
+ final_pairs [idx ]= pair_idx ;
383
+ final_pairs [pair_idx ]= idx ;
384
+ }
385
+ } else {
386
+ pos_to_level [idx ]= -1 ;
387
+ }
388
+ }
389
+ }
390
+
391
+ for (idx = 0 ;pos_to_level [idx ]!= -2 ; idx ++ ) {
392
+ bool ok = false;
393
+ if (pos_to_level [idx ]== -1 )
394
+ continue ;
395
+ for (int j = 0 ; final_pairs [j ]!= -2 ;j ++ ) {
396
+ if (final_pairs [j ]== -1 )
397
+ continue ;
398
+ if (final_pairs [j ]== idx ) {
399
+ if (idx == 0 )
400
+ first = j ;
401
+ ok = true;
402
+ break ;
403
+ }
404
+ }
405
+ if (!ok )
406
+ return NULL ;
407
+ }
408
+
409
+ if (pos_to_level [0 ] < 0 )
410
+ return NULL ;
411
+ if (first < 0 )
412
+ return NULL ;
413
+
414
+ return input + first ;
415
+ }
416
+
417
+
355
418
static bool
356
419
format_append_arg (struct format_context * format , const char * * * dst_argv , const char * arg )
357
420
{
@@ -362,7 +425,7 @@ format_append_arg(struct format_context *format, const char ***dst_argv, const c
362
425
const char * var = strstr (arg , "%(" );
363
426
const char * esc = strstr (arg , "%%" );
364
427
bool is_escaped = esc && (esc < var || !var );
365
- const char * closing = var && !is_escaped ? strchr (var , ')' ) : NULL ;
428
+ const char * closing = var && !is_escaped ? get_closing_brace (var + 1 ) : NULL ;
366
429
const char * next = is_escaped ? esc + 2 : closing ? closing + 1 : NULL ;
367
430
int len = var && !is_escaped ? var - arg : esc ? esc - arg + 1 : strlen (arg );
368
431
@@ -372,7 +435,7 @@ format_append_arg(struct format_context *format, const char ***dst_argv, const c
372
435
if (len && !string_format_from (format -> buf , & format -> bufpos , "%.*s" , len , arg ))
373
436
return false;
374
437
375
- if (var && !is_escaped && !format_expand_arg (format , var , next ))
438
+ if (var && !is_escaped && !format_expand_arg (format , var , next ))
376
439
return false;
377
440
378
441
arg = next ;
0 commit comments