diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2015-04-01 09:30:13 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2015-04-01 09:37:27 +0900 |
commit | 4e716fb779a3e02d11f3300f05879f86b0a73e62 (patch) | |
tree | 55a67ec87f15dc6f507ff75d163940c098e56a50 /src/lib/ecore_file/ecore_file.c | |
parent | abf3c3c4704f67db41c8ed230510bbaa2386cc42 (diff) |
ecore_file - fix nasty memory issues in ecore_file_app_exe_get()
valgrind was most unhappy with ecore_file_app_exe_get(). like:
==8331== Invalid write of size 1
==8331== at 0x68DE90A: ecore_file_app_exe_get (ecore_file.c:994)
==8331== Address 0x1348e58f is 0 bytes after a block of size 31 alloc'd
==8331== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==8331== Invalid write of size 1
==8331== at 0x68DE948: ecore_file_app_exe_get (ecore_file.c:1000)
==8331== Address 0x1348e599 is 10 bytes after a block of size 31 alloc'd
==8331== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
etc. etc. - so i rewrote it cleanly using strbuf to save code and
effort. cleaner now and ACTUALLY works correctly... and no valgrind
complaints.
@fix
Diffstat (limited to '')
-rw-r--r-- | src/lib/ecore_file/ecore_file.c | 151 |
1 files changed, 33 insertions, 118 deletions
diff --git a/src/lib/ecore_file/ecore_file.c b/src/lib/ecore_file/ecore_file.c index 372af03512..dc105db0c2 100644 --- a/src/lib/ecore_file/ecore_file.c +++ b/src/lib/ecore_file/ecore_file.c | |||
@@ -857,147 +857,62 @@ ecore_file_ls(const char *dir) | |||
857 | EAPI char * | 857 | EAPI char * |
858 | ecore_file_app_exe_get(const char *app) | 858 | ecore_file_app_exe_get(const char *app) |
859 | { | 859 | { |
860 | char *p, *pp, *exe1 = NULL, *exe2 = NULL; | 860 | Eina_Strbuf *buf; |
861 | char *exe = NULL; | 861 | char *exe; |
862 | int in_quot_dbl = 0, in_quot_sing = 0, restart = 0; | 862 | const char *p; |
863 | Eina_Bool in_qout_double = EINA_FALSE; | ||
864 | Eina_Bool in_qout_single = EINA_FALSE; | ||
863 | 865 | ||
864 | if (!app) return NULL; | 866 | if (!app) return NULL; |
865 | 867 | buf = eina_strbuf_new(); | |
866 | p = (char *)app; | 868 | if (!buf) return NULL; |
867 | restart: | 869 | p = app; |
868 | while ((*p) && (isspace((unsigned char)*p))) p++; | 870 | if ((p[0] == '~') && (p[1] == '/')) |
869 | exe1 = p; | ||
870 | while (*p) | ||
871 | { | 871 | { |
872 | if (in_quot_sing) | 872 | const char *home = getenv("HOME"); |
873 | { | 873 | if (home) eina_strbuf_append(buf, home); |
874 | if (*p == '\'') | ||
875 | in_quot_sing = 0; | ||
876 | } | ||
877 | else if (in_quot_dbl) | ||
878 | { | ||
879 | if (*p == '\"') | ||
880 | in_quot_dbl = 0; | ||
881 | } | ||
882 | else | ||
883 | { | ||
884 | if (*p == '\'') | ||
885 | in_quot_sing = 1; | ||
886 | else if (*p == '\"') | ||
887 | in_quot_dbl = 1; | ||
888 | if ((isspace((unsigned char)*p)) && ((p <= app) || (p[-1] == '\\'))) | ||
889 | break; | ||
890 | } | ||
891 | p++; | 874 | p++; |
892 | } | 875 | } |
893 | exe2 = p; | 876 | for (; *p; p++) |
894 | if (exe2 == exe1) return NULL; | ||
895 | if (*exe1 == '~') | ||
896 | { | 877 | { |
897 | char *homedir; | 878 | if (in_qout_double) |
898 | int len; | ||
899 | |||
900 | /* Skip ~ */ | ||
901 | exe1++; | ||
902 | |||
903 | homedir = getenv("HOME"); | ||
904 | if (!homedir) return NULL; | ||
905 | len = strlen(homedir); | ||
906 | exe = malloc(len + exe2 - exe1 + 2); | ||
907 | if (!exe) return NULL; | ||
908 | pp = exe; | ||
909 | if (len) | ||
910 | { | 879 | { |
911 | strcpy(exe, homedir); | 880 | if (*p == '\\') |
912 | pp += len; | ||
913 | if (*(pp - 1) != '/') | ||
914 | { | 881 | { |
915 | *pp = '/'; | 882 | if (p[1]) p++; |
916 | pp++; | 883 | eina_strbuf_append_char(buf, *p); |
917 | } | 884 | } |
885 | else if (*p == '"') in_qout_double = EINA_FALSE; | ||
886 | else eina_strbuf_append_char(buf, *p); | ||
918 | } | 887 | } |
919 | } | 888 | else if (in_qout_single) |
920 | else | ||
921 | { | ||
922 | exe = malloc(exe2 - exe1 + 1); | ||
923 | if (!exe) return NULL; | ||
924 | pp = exe; | ||
925 | } | ||
926 | p = exe1; | ||
927 | restart = 0; | ||
928 | in_quot_dbl = 0; | ||
929 | in_quot_sing = 0; | ||
930 | while (*p) | ||
931 | { | ||
932 | if (in_quot_sing) | ||
933 | { | 889 | { |
934 | if (*p == '\'') | 890 | if (*p == '\\') |
935 | in_quot_sing = 0; | ||
936 | else | ||
937 | { | ||
938 | *pp = *p; | ||
939 | pp++; | ||
940 | } | ||
941 | } | ||
942 | else if (in_quot_dbl) | ||
943 | { | ||
944 | if (*p == '\"') | ||
945 | in_quot_dbl = 0; | ||
946 | else | ||
947 | { | 891 | { |
948 | /* technically this is wrong. double quotes also accept | 892 | if (p[1]) p++; |
949 | * special chars: | 893 | eina_strbuf_append_char(buf, *p); |
950 | * | ||
951 | * $, `, \ | ||
952 | */ | ||
953 | *pp = *p; | ||
954 | pp++; | ||
955 | } | 894 | } |
895 | else if (*p == '\'') in_qout_single = EINA_FALSE; | ||
896 | else eina_strbuf_append_char(buf, *p); | ||
956 | } | 897 | } |
957 | else | 898 | else |
958 | { | 899 | { |
959 | /* technically we should handle special chars: | 900 | if (*p == '\\') |
960 | * | ||
961 | * $, `, \, etc. | ||
962 | */ | ||
963 | if ((p > exe1) && (p[-1] == '\\')) | ||
964 | { | 901 | { |
965 | if (*p != '\n') | 902 | if (p[1]) p++; |
966 | { | 903 | eina_strbuf_append_char(buf, *p); |
967 | *pp = *p; | ||
968 | pp++; | ||
969 | } | ||
970 | } | ||
971 | else if ((p > exe1) && (*p == '=')) | ||
972 | { | ||
973 | restart = 1; | ||
974 | *pp = *p; | ||
975 | pp++; | ||
976 | } | ||
977 | else if (*p == '\'') | ||
978 | in_quot_sing = 1; | ||
979 | else if (*p == '\"') | ||
980 | in_quot_dbl = 1; | ||
981 | else if (isspace((unsigned char)*p)) | ||
982 | { | ||
983 | if (restart) | ||
984 | { | ||
985 | if (exe) free(exe); | ||
986 | exe = NULL; | ||
987 | goto restart; | ||
988 | } | ||
989 | else | ||
990 | break; | ||
991 | } | 904 | } |
905 | else if (*p == '"') in_qout_double = EINA_TRUE; | ||
906 | else if (*p == '\'') in_qout_single = EINA_TRUE; | ||
992 | else | 907 | else |
993 | { | 908 | { |
994 | *pp = *p; | 909 | if (isspace((unsigned char)(*p))) break; |
995 | pp++; | 910 | eina_strbuf_append_char(buf, *p); |
996 | } | 911 | } |
997 | } | 912 | } |
998 | p++; | ||
999 | } | 913 | } |
1000 | *pp = 0; | 914 | exe = eina_strbuf_string_steal(buf); |
915 | eina_strbuf_free(buf); | ||
1001 | return exe; | 916 | return exe; |
1002 | } | 917 | } |
1003 | 918 | ||