Skip to content

Commit ad2a0db

Browse files
committed
Fix hash collision by using custom compare
1 parent 10d8292 commit ad2a0db

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

src/ast.hpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,24 @@ namespace Sass {
277277
// extra <std::vector> internally to maintain insertion order for interation.
278278
/////////////////////////////////////////////////////////////////////////////
279279
class Hashed {
280+
struct HashExpression {
281+
size_t operator() (Expression* ex) const {
282+
return ex ? ex->hash() : 0;
283+
}
284+
};
285+
struct CompareExpression {
286+
bool operator()(const Expression* lhs, const Expression* rhs) const {
287+
return lhs && rhs && *lhs == *rhs;
288+
}
289+
};
290+
typedef std::unordered_map<
291+
Expression*, // key
292+
Expression*, // value
293+
HashExpression, // hasher
294+
CompareExpression // compare
295+
> ExpressionMap;
280296
private:
281-
std::unordered_map<Expression*, Expression*> elements_;
297+
ExpressionMap elements_;
282298
std::vector<Expression*> list_;
283299
protected:
284300
size_t hash_;
@@ -287,7 +303,7 @@ namespace Sass {
287303
void reset_duplicate_key() { duplicate_key_ = 0; }
288304
virtual void adjust_after_pushing(std::pair<Expression*, Expression*> p) { }
289305
public:
290-
Hashed(size_t s = 0) : elements_(std::unordered_map<Expression*, Expression*>(s)), list_(std::vector<Expression*>())
306+
Hashed(size_t s = 0) : elements_(ExpressionMap(s)), list_(std::vector<Expression*>())
291307
{ elements_.reserve(s); list_.reserve(s); reset_duplicate_key(); }
292308
virtual ~Hashed();
293309
size_t length() const { return list_.size(); }
@@ -296,7 +312,7 @@ namespace Sass {
296312
Expression* at(Expression* k) const;
297313
bool has_duplicate_key() const { return duplicate_key_ != 0; }
298314
Expression* get_duplicate_key() const { return duplicate_key_; }
299-
const std::unordered_map<Expression*, Expression*> elements() { return elements_; }
315+
const ExpressionMap elements() { return elements_; }
300316
Hashed& operator<<(std::pair<Expression*, Expression*> p)
301317
{
302318
reset_hash();
@@ -324,7 +340,7 @@ namespace Sass {
324340
reset_duplicate_key();
325341
return *this;
326342
}
327-
const std::unordered_map<Expression*, Expression*>& pairs() const { return elements_; }
343+
const ExpressionMap& pairs() const { return elements_; }
328344
const std::vector<Expression*>& keys() const { return list_; }
329345

330346
std::unordered_map<Expression*, Expression*>::iterator end() { return elements_.end(); }

0 commit comments

Comments
 (0)