Skip to content

Commit 19ddc1e

Browse files
committed
fix(calculus, recognizer): memory leak due to unchecked regex error
Closes #171
1 parent 97cd661 commit 19ddc1e

File tree

2 files changed

+28
-19
lines changed

2 files changed

+28
-19
lines changed

src/rime/algo/calculus.cc

+21-18
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
#include <boost/algorithm/string.hpp>
88
#include <utf8.h>
99
#include <rime/algo/calculus.h>
10+
#include <rime/common.h>
1011

1112
namespace rime {
1213

14+
const double kAbbreviationPenalty = 0.5;
15+
const double kFuzzySpellingPenalty = 0.5;
16+
1317
Calculus::Calculus() {
1418
Register("xlit", &Transliteration::Parse);
1519
Register("xform", &Transformation::Parse);
@@ -33,8 +37,7 @@ Calculation* Calculus::Parse(const string& definition) {
3337
boost::is_from_range(definition[sep], definition[sep]));
3438
if (args.empty())
3539
return NULL;
36-
map<string,
37-
Calculation::Factory*>::iterator it = factories_.find(args[0]);
40+
auto it = factories_.find(args[0]);
3841
if (it == factories_.end())
3942
return NULL;
4043
Calculation* result = (*it->second)(args);
@@ -58,9 +61,9 @@ Calculation* Transliteration::Parse(const vector<string>& args) {
5861
char_map[cl] = cr;
5962
}
6063
if (cl == 0 && cr == 0) {
61-
Transliteration* x = new Transliteration;
64+
the<Transliteration> x(new Transliteration);
6265
x->char_map_.swap(char_map);
63-
return x;
66+
return x.release();
6467
}
6568
return NULL;
6669
}
@@ -101,17 +104,17 @@ Calculation* Transformation::Parse(const vector<string>& args) {
101104
const string& right(args[2]);
102105
if (left.empty())
103106
return NULL;
104-
Transformation* x = new Transformation;
107+
the<Transformation> x(new Transformation);
105108
x->pattern_.assign(left);
106109
x->replacement_.assign(right);
107-
return x;
110+
return x.release();
108111
}
109112

110113
bool Transformation::Apply(Spelling* spelling) {
111114
if (!spelling || spelling->str.empty())
112115
return false;
113-
string result(boost::regex_replace(spelling->str,
114-
pattern_, replacement_));
116+
string result = boost::regex_replace(spelling->str,
117+
pattern_, replacement_);
115118
if (result == spelling->str)
116119
return false;
117120
spelling->str.swap(result);
@@ -126,9 +129,9 @@ Calculation* Erasion::Parse(const vector<string>& args) {
126129
const string& pattern(args[1]);
127130
if (pattern.empty())
128131
return NULL;
129-
Erasion* x = new Erasion;
132+
the<Erasion> x(new Erasion);
130133
x->pattern_.assign(pattern);
131-
return x;
134+
return x.release();
132135
}
133136

134137
bool Erasion::Apply(Spelling* spelling) {
@@ -149,10 +152,10 @@ Calculation* Derivation::Parse(const vector<string>& args) {
149152
const string& right(args[2]);
150153
if (left.empty())
151154
return NULL;
152-
Derivation* x = new Derivation;
155+
the<Derivation> x(new Derivation);
153156
x->pattern_.assign(left);
154157
x->replacement_.assign(right);
155-
return x;
158+
return x.release();
156159
}
157160

158161
// Fuzzing
@@ -164,17 +167,17 @@ Calculation* Fuzzing::Parse(const vector<string>& args) {
164167
const string& right(args[2]);
165168
if (left.empty())
166169
return NULL;
167-
Fuzzing* x = new Fuzzing;
170+
the<Fuzzing> x(new Fuzzing);
168171
x->pattern_.assign(left);
169172
x->replacement_.assign(right);
170-
return x;
173+
return x.release();
171174
}
172175

173176
bool Fuzzing::Apply(Spelling* spelling) {
174177
bool result = Transformation::Apply(spelling);
175178
if (result) {
176179
spelling->properties.type = kFuzzySpelling;
177-
spelling->properties.credibility *= 0.5;
180+
spelling->properties.credibility *= kFuzzySpellingPenalty;
178181
}
179182
return result;
180183
}
@@ -188,17 +191,17 @@ Calculation* Abbreviation::Parse(const vector<string>& args) {
188191
const string& right(args[2]);
189192
if (left.empty())
190193
return NULL;
191-
Abbreviation* x = new Abbreviation;
194+
the<Abbreviation> x(new Abbreviation);
192195
x->pattern_.assign(left);
193196
x->replacement_.assign(right);
194-
return x;
197+
return x.release();
195198
}
196199

197200
bool Abbreviation::Apply(Spelling* spelling) {
198201
bool result = Transformation::Apply(spelling);
199202
if (result) {
200203
spelling->properties.type = kAbbreviation;
201-
spelling->properties.credibility *= 0.5;
204+
spelling->properties.credibility *= kAbbreviationPenalty;
202205
}
203206
return result;
204207
}

src/rime/gear/recognizer.cc

+7-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ static void load_patterns(RecognizerPatterns* patterns, an<ConfigMap> map) {
2222
auto value = As<ConfigValue>(it->second);
2323
if (!value)
2424
continue;
25-
(*patterns)[it->first] = value->str();
25+
try {
26+
boost::regex pattern(value->str());
27+
(*patterns)[it->first] = pattern;
28+
} catch (boost::regex_error& e) {
29+
LOG(ERROR) << "error parsing pattern /" << value->str() << "/: "
30+
<< e.what();
31+
}
2632
}
2733
}
2834

0 commit comments

Comments
 (0)