comparison src/getchar.c @ 2062:dae4cd29a0b7 v7.2.347

updated for version 7.2.347 Problem: Crash when executing <expr> mapping redefines that same mapping. Solution: Save the values used before evaluating the expression.
author Bram Moolenaar <bram@zimbu.org>
date Wed, 27 Jan 2010 17:31:43 +0100
parents ada3271481ce
children 2bd96108392e
comparison
equal deleted inserted replaced
2061:2f6e519726f1 2062:dae4cd29a0b7
2387 } 2387 }
2388 2388
2389 /* complete match */ 2389 /* complete match */
2390 if (keylen >= 0 && keylen <= typebuf.tb_len) 2390 if (keylen >= 0 && keylen <= typebuf.tb_len)
2391 { 2391 {
2392 #ifdef FEAT_EVAL
2393 int save_m_expr;
2394 int save_m_noremap;
2395 int save_m_silent;
2396 char_u *save_m_keys;
2397 char_u *save_m_str;
2398 #else
2399 # define save_m_noremap mp->m_noremap
2400 # define save_m_silent mp->m_silent
2401 #endif
2402
2392 /* write chars to script file(s) */ 2403 /* write chars to script file(s) */
2393 if (keylen > typebuf.tb_maplen) 2404 if (keylen > typebuf.tb_maplen)
2394 gotchars(typebuf.tb_buf + typebuf.tb_off 2405 gotchars(typebuf.tb_buf + typebuf.tb_off
2395 + typebuf.tb_maplen, 2406 + typebuf.tb_maplen,
2396 keylen - typebuf.tb_maplen); 2407 keylen - typebuf.tb_maplen);
2429 0, TRUE, FALSE); 2440 0, TRUE, FALSE);
2430 } 2441 }
2431 #endif 2442 #endif
2432 2443
2433 #ifdef FEAT_EVAL 2444 #ifdef FEAT_EVAL
2445 /* Copy the values from *mp that are used, because
2446 * evaluating the expression may invoke a function
2447 * that redefines the mapping, thereby making *mp
2448 * invalid. */
2449 save_m_expr = mp->m_expr;
2450 save_m_noremap = mp->m_noremap;
2451 save_m_silent = mp->m_silent;
2452 save_m_keys = NULL; /* only saved when needed */
2453 save_m_str = NULL; /* only saved when needed */
2454
2434 /* 2455 /*
2435 * Handle ":map <expr>": evaluate the {rhs} as an 2456 * Handle ":map <expr>": evaluate the {rhs} as an
2436 * expression. Save and restore the typeahead so that 2457 * expression. Save and restore the typeahead so that
2437 * getchar() can be used. Also save and restore the 2458 * getchar() can be used. Also save and restore the
2438 * command line for "normal :". 2459 * command line for "normal :".
2444 2465
2445 save_typeahead(&tabuf); 2466 save_typeahead(&tabuf);
2446 if (tabuf.typebuf_valid) 2467 if (tabuf.typebuf_valid)
2447 { 2468 {
2448 vgetc_busy = 0; 2469 vgetc_busy = 0;
2449 s = eval_map_expr(mp->m_str, NUL); 2470 save_m_keys = vim_strsave(mp->m_keys);
2471 save_m_str = vim_strsave(mp->m_str);
2472 s = eval_map_expr(save_m_str, NUL);
2450 vgetc_busy = save_vgetc_busy; 2473 vgetc_busy = save_vgetc_busy;
2451 } 2474 }
2452 else 2475 else
2453 s = NULL; 2476 s = NULL;
2454 restore_typeahead(&tabuf); 2477 restore_typeahead(&tabuf);
2468 if (s == NULL) 2491 if (s == NULL)
2469 i = FAIL; 2492 i = FAIL;
2470 else 2493 else
2471 { 2494 {
2472 i = ins_typebuf(s, 2495 i = ins_typebuf(s,
2473 mp->m_noremap != REMAP_YES 2496 save_m_noremap != REMAP_YES
2474 ? mp->m_noremap 2497 ? save_m_noremap
2475 : STRNCMP(s, mp->m_keys, 2498 : STRNCMP(s,
2499 #ifdef FEAT_EVAL
2500 save_m_keys != NULL ? save_m_keys :
2501 #endif
2502 mp->m_keys,
2476 (size_t)keylen) != 0 2503 (size_t)keylen) != 0
2477 ? REMAP_YES : REMAP_SKIP, 2504 ? REMAP_YES : REMAP_SKIP,
2478 0, TRUE, cmd_silent || mp->m_silent); 2505 0, TRUE, cmd_silent || save_m_silent);
2479 #ifdef FEAT_EVAL 2506 #ifdef FEAT_EVAL
2480 if (mp->m_expr) 2507 if (save_m_expr)
2481 vim_free(s); 2508 vim_free(s);
2482 #endif 2509 #endif
2483 } 2510 }
2511 #ifdef FEAT_EVAL
2512 vim_free(save_m_keys);
2513 vim_free(save_m_str);
2514 #endif
2484 if (i == FAIL) 2515 if (i == FAIL)
2485 { 2516 {
2486 c = -1; 2517 c = -1;
2487 break; 2518 break;
2488 } 2519 }