No public description PiperOrigin-RevId: 951751486
diff --git a/src/hunspell/affixmgr.cxx b/src/hunspell/affixmgr.cxx index 5cb2356..40b8a65 100644 --- a/src/hunspell/affixmgr.cxx +++ b/src/hunspell/affixmgr.cxx
@@ -3725,13 +3725,21 @@ } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); + if (*rl) { + delete *rl; + *rl = NULL; + } return 1; } /* now parse the num lines to read in the remainder of the table */ char * nl; for (int j=0; j < numrl; j++) { - if (!(nl = af->getline())) return 1; + if (!(nl = af->getline())) { + delete *rl; + *rl = NULL; + return 1; + } mychomp(nl); tp = nl; i = 0; @@ -3767,6 +3775,8 @@ if (pattern2) free(pattern2); HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); + delete *rl; + *rl = NULL; return 1; } (*rl)->add(pattern, pattern2); @@ -3822,13 +3832,26 @@ } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); + if (phone) { + if (phone->rules) free(phone->rules); + free(phone); + phone = NULL; + } return 1; } /* now parse the phone->num lines to read in the remainder of the table */ char * nl; for (int j=0; j < phone->num; j++) { - if (!(nl = af->getline())) return 1; + if (!(nl = af->getline())) { + for (int k = 0; k < 2 * (phone->num + 1); k++) { + if (phone->rules[k]) free(phone->rules[k]); + } + free(phone->rules); + free(phone); + phone = NULL; + return 1; + } mychomp(nl); tp = nl; i = 0; @@ -3841,7 +3864,13 @@ case 0: { if (strncmp(piece,"PHONE",5) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); - phone->num = 0; + for (int k = 0; k < 2 * (phone->num + 1); + k++) { + if (phone->rules[k]) free(phone->rules[k]); + } + free(phone->rules); + free(phone); + phone = NULL; return 1; } break; @@ -3856,7 +3885,12 @@ } if ((!(phone->rules[j * 2])) || (!(phone->rules[j * 2 + 1]))) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); - phone->num = 0; + for (int k = 0; k < 2 * (phone->num + 1); k++) { + if (phone->rules[k]) free(phone->rules[k]); + } + free(phone->rules); + free(phone); + phone = NULL; return 1; } } @@ -3902,13 +3936,28 @@ } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); + if (checkcpdtable) { + free(checkcpdtable); + checkcpdtable = NULL; + } + numcheckcpd = 0; return 1; } /* now parse the numcheckcpd lines to read in the remainder of the table */ char * nl; for (int j=0; j < numcheckcpd; j++) { - if (!(nl = af->getline())) return 1; + if (!(nl = af->getline())) { + for (int k = 0; k < j; k++) { + if (checkcpdtable[k].pattern) free(checkcpdtable[k].pattern); + if (checkcpdtable[k].pattern2) free(checkcpdtable[k].pattern2); + if (checkcpdtable[k].pattern3) free(checkcpdtable[k].pattern3); + } + free(checkcpdtable); + checkcpdtable = NULL; + numcheckcpd = 0; + return 1; + } mychomp(nl); tp = nl; i = 0; @@ -3924,6 +3973,16 @@ case 0: { if (strncmp(piece,"CHECKCOMPOUNDPATTERN",20) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); + for (int k = 0; k < j; k++) { + if (checkcpdtable[k].pattern) + free(checkcpdtable[k].pattern); + if (checkcpdtable[k].pattern2) + free(checkcpdtable[k].pattern2); + if (checkcpdtable[k].pattern3) + free(checkcpdtable[k].pattern3); + } + free(checkcpdtable); + checkcpdtable = NULL; numcheckcpd = 0; return 1; } @@ -3955,6 +4014,13 @@ } if ((!(checkcpdtable[j].pattern)) || (!(checkcpdtable[j].pattern2))) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); + for (int k = 0; k <= j; k++) { + if (checkcpdtable[k].pattern) free(checkcpdtable[k].pattern); + if (checkcpdtable[k].pattern2) free(checkcpdtable[k].pattern2); + if (checkcpdtable[k].pattern3) free(checkcpdtable[k].pattern3); + } + free(checkcpdtable); + checkcpdtable = NULL; numcheckcpd = 0; return 1; } @@ -4211,13 +4277,26 @@ } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); + if (breaktable) { + free(breaktable); + breaktable = NULL; + } + numbreak = -1; return 1; } /* now parse the numbreak lines to read in the remainder of the table */ char * nl; for (int j=0; j < numbreak; j++) { - if (!(nl = af->getline())) return 1; + if (!(nl = af->getline())) { + for (int k = 0; k < j; k++) { + if (breaktable[k]) free(breaktable[k]); + } + free(breaktable); + breaktable = NULL; + numbreak = -1; + return 1; + } mychomp(nl); tp = nl; i = 0; @@ -4228,7 +4307,12 @@ case 0: { if (strncmp(piece,"BREAK",5) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); - numbreak = 0; + for (int k = 0; k < j; k++) { + if (breaktable[k]) free(breaktable[k]); + } + free(breaktable); + breaktable = NULL; + numbreak = -1; return 1; } break; @@ -4245,7 +4329,12 @@ } if (!breaktable) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); - numbreak = 0; + for (int k = 0; k <= j; k++) { + if (breaktable[k]) free(breaktable[k]); + } + free(breaktable); + breaktable = NULL; + numbreak = -1; return 1; } } @@ -4278,6 +4367,37 @@ } } +namespace { + +void clean_affentries(std::vector<affentry>& affentries) { + for (affentry& entry : affentries) { + if (entry.strip) { + free(entry.strip); + entry.strip = NULL; + } + if (entry.appnd) { + free(entry.appnd); + entry.appnd = NULL; + } + if (entry.opts & aeLONGCOND) { + if (entry.c.l.conds2) { + free(entry.c.l.conds2); + entry.c.l.conds2 = NULL; + } + } + if (entry.morphcode && !(entry.opts & aeALIASM)) { + free(entry.morphcode); + entry.morphcode = NULL; + } + if (entry.contclass && !(entry.opts & aeALIASF)) { + free(entry.contclass); + entry.contclass = NULL; + } + } +} + +} // namespace + int AffixMgr::parse_affix(char * line, const char at, FileMgr * af, char * dupflags) { int numents = 0; // number of affentry structures to parse @@ -4358,6 +4478,7 @@ HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); free(err); } + clean_affentries(affentries); return 1; } @@ -4365,7 +4486,10 @@ std::vector<affentry>::iterator start = affentries.begin(); std::vector<affentry>::iterator end = affentries.end(); for (std::vector<affentry>::iterator entry = start; entry != end; ++entry) { - if (!(nl = af->getline())) return 1; + if (!(nl = af->getline())) { + clean_affentries(affentries); + return 1; + } mychomp(nl); tp = nl; i = 0; @@ -4394,6 +4518,7 @@ af->getlinenum(), err); free(err); } + clean_affentries(affentries); return 1; } @@ -4493,7 +4618,10 @@ reverseword(piece); reverse_condition(piece); } - if (encodeit(*entry, piece)) return 1; + if (encodeit(*entry, piece)) { + clean_affentries(affentries); + return 1; + } break; } @@ -4512,7 +4640,10 @@ tp = tp + strlen(tp); } entry->morphcode = mystrdup(piece); - if (!entry->morphcode) return 1; + if (!entry->morphcode) { + clean_affentries(affentries); + return 1; + } } break; } @@ -4530,6 +4661,7 @@ af->getlinenum(), err); free(err); } + clean_affentries(affentries); return 1; }