Mercurial > mplayer.hg
comparison m_option.c @ 35272:8756cd0da7b7
Fix memleaks for error case.
author | reimar |
---|---|
date | Tue, 06 Nov 2012 21:59:59 +0000 |
parents | 1c18199bbf7c |
children | 388b4cc85c0e |
comparison
equal
deleted
inserted
replaced
35271:8c16fe658af0 | 35272:8756cd0da7b7 |
---|---|
960 #define VAL(x) (*(char***)(x)) | 960 #define VAL(x) (*(char***)(x)) |
961 | 961 |
962 static int parse_subconf(const m_option_t* opt,const char *name, const char *param, void* dst, int src) { | 962 static int parse_subconf(const m_option_t* opt,const char *name, const char *param, void* dst, int src) { |
963 char *subparam; | 963 char *subparam; |
964 char *subopt; | 964 char *subopt; |
965 int nr = 0,i,r; | 965 int nr = 0,i,r = 1; |
966 const m_option_t *subopts; | 966 const m_option_t *subopts; |
967 const char *p; | 967 const char *p; |
968 char** lst = NULL; | 968 char** lst = NULL; |
969 | 969 |
970 if (param == NULL || strlen(param) == 0) | 970 if (param == NULL || strlen(param) == 0) |
992 optlen = strcspn(p, "\""); | 992 optlen = strcspn(p, "\""); |
993 av_strlcpy(subparam, p, optlen + 1); | 993 av_strlcpy(subparam, p, optlen + 1); |
994 p = &p[optlen]; | 994 p = &p[optlen]; |
995 if (p[0] != '"') { | 995 if (p[0] != '"') { |
996 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Terminating '\"' missing for '%s'\n", subopt); | 996 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Terminating '\"' missing for '%s'\n", subopt); |
997 return M_OPT_INVALID; | 997 r = M_OPT_INVALID; |
998 goto out; | |
998 } | 999 } |
999 p = &p[1]; | 1000 p = &p[1]; |
1000 } else if (p[0] == '%') { | 1001 } else if (p[0] == '%') { |
1001 p = &p[1]; | 1002 p = &p[1]; |
1002 optlen = (int)strtol(p, (char**)&p, 0); | 1003 optlen = (int)strtol(p, (char**)&p, 0); |
1003 if (!p || p[0] != '%' || (optlen > strlen(p) - 1)) { | 1004 if (!p || p[0] != '%' || (optlen > strlen(p) - 1)) { |
1004 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid length %i for '%s'\n", optlen, subopt); | 1005 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid length %i for '%s'\n", optlen, subopt); |
1005 return M_OPT_INVALID; | 1006 r = M_OPT_INVALID; |
1007 goto out; | |
1006 } | 1008 } |
1007 p = &p[1]; | 1009 p = &p[1]; |
1008 av_strlcpy(subparam, p, optlen + 1); | 1010 av_strlcpy(subparam, p, optlen + 1); |
1009 p = &p[optlen]; | 1011 p = &p[optlen]; |
1010 } else { | 1012 } else { |
1015 } | 1017 } |
1016 if (p[0] == ':') | 1018 if (p[0] == ':') |
1017 p = &p[1]; | 1019 p = &p[1]; |
1018 else if (p[0]) { | 1020 else if (p[0]) { |
1019 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Incorrect termination for '%s'\n", subopt); | 1021 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Incorrect termination for '%s'\n", subopt); |
1020 return M_OPT_INVALID; | 1022 r = M_OPT_INVALID; |
1023 goto out; | |
1021 } | 1024 } |
1022 | 1025 |
1023 switch(sscanf_ret) | 1026 switch(sscanf_ret) |
1024 { | 1027 { |
1025 case 1: | 1028 case 1: |
1028 for(i = 0 ; subopts[i].name ; i++) { | 1031 for(i = 0 ; subopts[i].name ; i++) { |
1029 if(!strcmp(subopts[i].name,subopt)) break; | 1032 if(!strcmp(subopts[i].name,subopt)) break; |
1030 } | 1033 } |
1031 if(!subopts[i].name) { | 1034 if(!subopts[i].name) { |
1032 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Unknown suboption %s\n",name,subopt); | 1035 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Unknown suboption %s\n",name,subopt); |
1033 return M_OPT_UNKNOWN; | 1036 r = M_OPT_UNKNOWN; |
1037 goto out; | |
1034 } | 1038 } |
1035 r = m_option_parse(&subopts[i],subopt, | 1039 r = m_option_parse(&subopts[i],subopt, |
1036 subparam[0] == 0 ? NULL : subparam,NULL,src); | 1040 subparam[0] == 0 ? NULL : subparam,NULL,src); |
1037 if(r < 0) return r; | 1041 if(r < 0) goto out; |
1038 if(dst) { | 1042 if(dst) { |
1039 lst = realloc(lst,2 * (nr+2) * sizeof(char*)); | 1043 lst = realloc(lst,2 * (nr+2) * sizeof(char*)); |
1040 lst[2*nr] = strdup(subopt); | 1044 lst[2*nr] = strdup(subopt); |
1041 lst[2*nr+1] = subparam[0] == 0 ? NULL : strdup(subparam); | 1045 lst[2*nr+1] = subparam[0] == 0 ? NULL : strdup(subparam); |
1042 memset(&lst[2*(nr+1)],0,2*sizeof(char*)); | 1046 memset(&lst[2*(nr+1)],0,2*sizeof(char*)); |
1044 } | 1048 } |
1045 break; | 1049 break; |
1046 } | 1050 } |
1047 } | 1051 } |
1048 | 1052 |
1053 if(dst) | |
1054 VAL(dst) = lst; | |
1055 r = 1; | |
1056 | |
1057 out: | |
1049 free(subparam); | 1058 free(subparam); |
1050 free(subopt); | 1059 free(subopt); |
1051 if(dst) | 1060 |
1052 VAL(dst) = lst; | 1061 return r; |
1053 | |
1054 return 1; | |
1055 } | 1062 } |
1056 | 1063 |
1057 const m_option_type_t m_option_type_subconfig = { | 1064 const m_option_type_t m_option_type_subconfig = { |
1058 "Subconfig", | 1065 "Subconfig", |
1059 "The syntax is -option opt1=foo:flag:opt2=blah", | 1066 "The syntax is -option opt1=foo:flag:opt2=blah", |