xaizek / vifm (License: GPLv2+) (since 2018-12-07)
Vifm is a file manager with curses interface, which provides Vi[m]-like environment for managing objects within file systems, extended with some useful ideas from mutt.
Commit 12293e47d8dbdd5c11af8acdb343cdd106e99aa3

Fix null pointer access error with parse_range.
Return value of one functino wasn't examined.

Found by clang-checker.
Author: xaizek
Author date (UTC): 2012-10-18 14:51
Committer name: xaizek
Committer date (UTC): 2012-10-18 14:51
Parent(s): 420669eacbabdc568436d80abb8e728af686d32a
Signing key:
Tree: b5ed388bafaf2753d7312be9c62629c100227914
File Lines added Lines deleted
src/engine/cmds.c 87 72
src/engine/cmds.h 2 2
File src/engine/cmds.c changed (mode: 100644) (index 4b9874928..abe4bb5c3)
... ... typedef struct
75 75 static inner_t *inner; static inner_t *inner;
76 76 static cmds_conf_t *cmds_conf; static cmds_conf_t *cmds_conf;
77 77
78 static const char * parse_range(const char *cmd, cmd_info_t *cmd_info);
79 78 static const char * parse_limit(const char *cmd, cmd_info_t *cmd_info); static const char * parse_limit(const char *cmd, cmd_info_t *cmd_info);
80 79 static const char * correct_limit(const char *cmd, cmd_info_t *cmd_info); static const char * correct_limit(const char *cmd, cmd_info_t *cmd_info);
81 80 static int udf_is_ambiguous(const char *name); static int udf_is_ambiguous(const char *name);
 
... ... static const char * parse_tail(cmd_t *cur, const char *cmd,
83 82 cmd_info_t *cmd_info); cmd_info_t *cmd_info);
84 83 static const char *get_cmd_name(const char *cmd, char *buf, size_t buf_len); static const char *get_cmd_name(const char *cmd, char *buf, size_t buf_len);
85 84 static void init_cmd_info(cmd_info_t *cmd_info); static void init_cmd_info(cmd_info_t *cmd_info);
86 static const char * skip_prefix_commands(const char *cmd);
85 static const char * skip_prefix_commands(const char cmd[]);
87 86 static cmd_t * find_cmd(const char *name); static cmd_t * find_cmd(const char *name);
87 static const char * parse_range(const char cmd[], cmd_info_t *cmd_info);
88 88 static int complete_cmd_args(cmd_t *cur, const char *args, static int complete_cmd_args(cmd_t *cur, const char *args,
89 89 cmd_info_t *cmd_info); cmd_info_t *cmd_info);
90 90 static void complete_cmd_name(const char *cmd_name, int user_only); static void complete_cmd_name(const char *cmd_name, int user_only);
 
... ... execute_cmd(const char *cmd)
309 309 return result; return result;
310 310 } }
311 311
312 /* Returns NULL on invalid range */
313 static const char *
314 parse_range(const char *cmd, cmd_info_t *cmd_info)
315 {
316 cmd = skip_whitespace(cmd);
317
318 if(isalpha(*cmd) || *cmd == '!' || *cmd == '\0')
319 return cmd;
320
321 for(;;)
322 {
323 cmd_info->begin = cmd_info->end;
324
325 cmd = parse_limit(cmd, cmd_info);
326
327 if(cmd == NULL)
328 return NULL;
329
330 cmd = correct_limit(cmd, cmd_info);
331
332 if(cmd_info->begin == NOT_DEF)
333 cmd_info->begin = cmd_info->end;
334
335 cmd = skip_whitespace(cmd);
336
337 if(*cmd != ',')
338 break;
339
340 cmd++;
341
342 cmd = skip_whitespace(cmd);
343 }
344
345 return cmd;
346 }
347
348 312 static const char * static const char *
349 313 parse_limit(const char *cmd, cmd_info_t *cmd_info) parse_limit(const char *cmd, cmd_info_t *cmd_info)
350 314 { {
 
... ... get_cmd_info(const char *cmd, cmd_info_t *info)
546 510 } }
547 511
548 512 int int
549 complete_cmd(const char *cmd)
513 complete_cmd(const char cmd[])
550 514 { {
551 515 cmd_info_t cmd_info; cmd_info_t cmd_info;
552 char cmd_name[256];
553 const char *begin, *args, *cmd_name_pos;
516 const char *begin, *cmd_name_pos;
554 517 size_t prefix_len; size_t prefix_len;
555 cmd_t *cur;
556 518
557 519 begin = cmd; begin = cmd;
558 520 cmd = skip_prefix_commands(begin); cmd = skip_prefix_commands(begin);
 
... ... complete_cmd(const char *cmd)
561 523 init_cmd_info(&cmd_info); init_cmd_info(&cmd_info);
562 524
563 525 cmd_name_pos = parse_range(cmd, &cmd_info); cmd_name_pos = parse_range(cmd, &cmd_info);
564 args = get_cmd_name(cmd_name_pos, cmd_name, sizeof(cmd_name));
565 cur = find_cmd(cmd_name);
566
567 if(*args == '\0' && *args != '!' && strcmp(cmd_name, "!") != 0)
526 if(cmd_name_pos != NULL)
568 527 { {
569 complete_cmd_name(cmd_name, 0);
570 prefix_len += cmd_name_pos - cmd;
571 }
572 else
573 {
574 prefix_len += args - cmd;
575 prefix_len += complete_cmd_args(cur, args, &cmd_info);
528 char cmd_name[256];
529 const char *args;
530 cmd_t *cur;
531
532 args = get_cmd_name(cmd_name_pos, cmd_name, sizeof(cmd_name));
533 cur = find_cmd(cmd_name);
534
535 if(*args == '\0' && *args != '!' && strcmp(cmd_name, "!") != 0)
536 {
537 complete_cmd_name(cmd_name, 0);
538 prefix_len += cmd_name_pos - cmd;
539 }
540 else
541 {
542 prefix_len += args - cmd;
543 prefix_len += complete_cmd_args(cur, args, &cmd_info);
544 }
576 545 } }
577 546
578 547 return prefix_len; return prefix_len;
579 548 } }
580 549
550 /* Skips prefix commands (which can be followed by an arbitrary command) at the
551 * beginning of command-line. */
581 552 static const char * static const char *
582 skip_prefix_commands(const char *cmd)
553 skip_prefix_commands(const char cmd[])
583 554 { {
584 555 cmd_info_t cmd_info; cmd_info_t cmd_info;
585 char cmd_name[256];
586 const char *args;
587 556 const char *cmd_name_pos; const char *cmd_name_pos;
588 cmd_t *cur;
589 557
590 558 init_cmd_info(&cmd_info); init_cmd_info(&cmd_info);
591 559
592 560 cmd_name_pos = parse_range(cmd, &cmd_info); cmd_name_pos = parse_range(cmd, &cmd_info);
593 args = get_cmd_name(cmd_name_pos, cmd_name, sizeof(cmd_name));
594 cur = find_cmd(cmd_name);
595 while(cur != NULL && *args != '\0')
561 if(cmd_name_pos != NULL)
596 562 { {
597 int offset = cmds_conf->skip_at_beginning(cur->id, args);
598 if(offset >= 0)
599 {
600 int delta = (args - cmd) + offset;
601 cmd += delta;
602 init_cmd_info(&cmd_info);
603 cmd_name_pos = parse_range(cmd, &cmd_info);
604 args = get_cmd_name(cmd_name_pos, cmd_name, sizeof(cmd_name));
605 }
606 else
563 char cmd_name[256];
564 const char *args;
565 cmd_t *cur;
566
567 args = get_cmd_name(cmd_name_pos, cmd_name, sizeof(cmd_name));
568 cur = find_cmd(cmd_name);
569 while(cur != NULL && *args != '\0')
607 570 { {
608 break;
571 int offset = cmds_conf->skip_at_beginning(cur->id, args);
572 if(offset >= 0)
573 {
574 int delta = (args - cmd) + offset;
575 cmd += delta;
576 init_cmd_info(&cmd_info);
577 cmd_name_pos = parse_range(cmd, &cmd_info);
578 if(cmd_name_pos == NULL)
579 {
580 break;
581 }
582 args = get_cmd_name(cmd_name_pos, cmd_name, sizeof(cmd_name));
583 }
584 else
585 {
586 break;
587 }
588 cur = find_cmd(cmd_name);
609 589 } }
610 cur = find_cmd(cmd_name);
611 590 } }
612 591 return cmd; return cmd;
613 592 } }
 
... ... find_cmd(const char *name)
627 606 return result; return result;
628 607 } }
629 608
609 /* Returns NULL on invalid range. */
610 static const char *
611 parse_range(const char cmd[], cmd_info_t *cmd_info)
612 {
613 cmd = skip_whitespace(cmd);
614
615 if(isalpha(*cmd) || *cmd == '!' || *cmd == '\0')
616 return cmd;
617
618 for(;;)
619 {
620 cmd_info->begin = cmd_info->end;
621
622 cmd = parse_limit(cmd, cmd_info);
623
624 if(cmd == NULL)
625 return NULL;
626
627 cmd = correct_limit(cmd, cmd_info);
628
629 if(cmd_info->begin == NOT_DEF)
630 cmd_info->begin = cmd_info->end;
631
632 cmd = skip_whitespace(cmd);
633
634 if(*cmd != ',')
635 break;
636
637 cmd++;
638
639 cmd = skip_whitespace(cmd);
640 }
641
642 return cmd;
643 }
644
630 645 static const char * static const char *
631 646 get_cmd_name(const char *cmd, char *buf, size_t buf_len) get_cmd_name(const char *cmd, char *buf, size_t buf_len)
632 647 { {
File src/engine/cmds.h changed (mode: 100644) (index 19c24e6cf..cd7202b3c)
... ... int get_cmd_id(const char *cmd);
120 120 /* Returns command id */ /* Returns command id */
121 121 int get_cmd_info(const char *cmd, cmd_info_t *info); int get_cmd_info(const char *cmd, cmd_info_t *info);
122 122
123 /* Returns offset in cmd, where completion elements should be pasted */
124 int complete_cmd(const char *cmd);
123 /* Returns offset in cmd, where completion elements should be pasted. */
124 int complete_cmd(const char cmd[]);
125 125
126 126 void add_builtin_commands(const cmd_add_t *cmds, int count); void add_builtin_commands(const cmd_add_t *cmds, int count);
127 127
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master