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",