Mercurial > vim
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 } |