Lines 2426-2428
Link Here
|
2426 |
return True; |
2426 |
return True; |
2427 |
} |
2427 |
} |
2428 |
|
2428 |
|
|
|
2429 |
|
2430 |
/******************************************************************* |
2431 |
Add a shell escape character '\' to any character not in a known list |
2432 |
of characters. UNIX charset format. |
2433 |
*******************************************************************/ |
2434 |
|
2435 |
#define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabdefghijklmnopqrstuvwxyz_/ \t.," |
2436 |
#define INSIDE_DQUOTE_LIST "$`\n\"\\" |
2437 |
|
2438 |
char *escape_shell_string(const char *src) |
2439 |
{ |
2440 |
size_t srclen = strlen(src); |
2441 |
char *ret = SMB_MALLOC((srclen * 2) + 1); |
2442 |
char *dest = ret; |
2443 |
BOOL in_s_quote = False; |
2444 |
BOOL in_d_quote = False; |
2445 |
BOOL next_escaped = False; |
2446 |
|
2447 |
if (!ret) { |
2448 |
return NULL; |
2449 |
} |
2450 |
|
2451 |
while (*src) { |
2452 |
size_t c_size = next_mb_char_size(src); |
2453 |
|
2454 |
if (c_size == (size_t)-1) { |
2455 |
SAFE_FREE(ret); |
2456 |
return NULL; |
2457 |
} |
2458 |
|
2459 |
if (c_size > 1) { |
2460 |
memcpy(dest, src, c_size); |
2461 |
src += c_size; |
2462 |
dest += c_size; |
2463 |
next_escaped = False; |
2464 |
continue; |
2465 |
} |
2466 |
|
2467 |
/* |
2468 |
* Deal with backslash escaped state. |
2469 |
* This only lasts for one character. |
2470 |
*/ |
2471 |
|
2472 |
if (next_escaped) { |
2473 |
*dest++ = *src++; |
2474 |
next_escaped = False; |
2475 |
continue; |
2476 |
} |
2477 |
|
2478 |
/* |
2479 |
* Deal with single quote state. The |
2480 |
* only thing we care about is exiting |
2481 |
* this state. |
2482 |
*/ |
2483 |
|
2484 |
if (in_s_quote) { |
2485 |
if (*src == '\'') { |
2486 |
in_s_quote = False; |
2487 |
} |
2488 |
*dest++ = *src++; |
2489 |
continue; |
2490 |
} |
2491 |
|
2492 |
/* |
2493 |
* Deal with double quote state. The most |
2494 |
* complex state. We must cope with \, meaning |
2495 |
* possibly escape next char (depending what it |
2496 |
* is), ", meaning exit this state, and possibly |
2497 |
* add an \ escape to any unprotected character |
2498 |
* (listed in INSIDE_DQUOTE_LIST). |
2499 |
*/ |
2500 |
|
2501 |
if (in_d_quote) { |
2502 |
if (*src == '\\') { |
2503 |
/* |
2504 |
* Next character might be escaped. |
2505 |
* We have to peek. Inside double |
2506 |
* quotes only INSIDE_DQUOTE_LIST |
2507 |
* characters are escaped by a \. |
2508 |
*/ |
2509 |
|
2510 |
char nextchar; |
2511 |
|
2512 |
c_size = next_mb_char_size(&src[1]); |
2513 |
if (c_size == (size_t)-1) { |
2514 |
SAFE_FREE(ret); |
2515 |
return NULL; |
2516 |
} |
2517 |
if (c_size > 1) { |
2518 |
/* |
2519 |
* Don't escape the next char. |
2520 |
* Just copy the \. |
2521 |
*/ |
2522 |
*dest++ = *src++; |
2523 |
continue; |
2524 |
} |
2525 |
|
2526 |
nextchar = src[1]; |
2527 |
|
2528 |
if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) { |
2529 |
next_escaped = True; |
2530 |
} |
2531 |
*dest++ = *src++; |
2532 |
continue; |
2533 |
} |
2534 |
|
2535 |
if (*src == '\"') { |
2536 |
/* Exit double quote state. */ |
2537 |
in_d_quote = False; |
2538 |
*dest++ = *src++; |
2539 |
continue; |
2540 |
} |
2541 |
|
2542 |
/* |
2543 |
* We know the character isn't \ or ", |
2544 |
* so escape it if it's any of the other |
2545 |
* possible unprotected characters. |
2546 |
*/ |
2547 |
|
2548 |
if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) { |
2549 |
*dest++ = '\\'; |
2550 |
} |
2551 |
*dest++ = *src++; |
2552 |
continue; |
2553 |
} |
2554 |
|
2555 |
/* |
2556 |
* From here to the end of the loop we're |
2557 |
* not in the single or double quote state. |
2558 |
*/ |
2559 |
|
2560 |
if (*src == '\\') { |
2561 |
/* Next character must be escaped. */ |
2562 |
next_escaped = True; |
2563 |
*dest++ = *src++; |
2564 |
continue; |
2565 |
} |
2566 |
|
2567 |
if (*src == '\'') { |
2568 |
/* Go into single quote state. */ |
2569 |
in_s_quote = True; |
2570 |
*dest++ = *src++; |
2571 |
continue; |
2572 |
} |
2573 |
|
2574 |
if (*src == '\"') { |
2575 |
/* Go into double quote state. */ |
2576 |
in_d_quote = True; |
2577 |
*dest++ = *src++; |
2578 |
continue; |
2579 |
} |
2580 |
|
2581 |
/* Check if we need to escape the character. */ |
2582 |
|
2583 |
if (!strchr(INCLUDE_LIST, (int)*src)) { |
2584 |
*dest++ = '\\'; |
2585 |
} |
2586 |
*dest++ = *src++; |
2587 |
} |
2588 |
*dest++ = '\0'; |
2589 |
return ret; |
2590 |
} |