File 648f763e-Fix-memory-corruption-on-error-in-parse_selector_sch.patch of Package libsass.7438
From 648f763ede97f9a2c2c843a0a18ac18bbde3507b Mon Sep 17 00:00:00 2001
From: Marcel Greter <marcel.greter@ocbnet.ch>
Date: Fri, 6 Oct 2017 18:44:25 +0200
Subject: [PATCH] Fix memory corruption on error in parse_selector_schema
---
src/eval.cpp | 19 ++++++++++++++++++-
src/file.cpp | 2 +-
2 files changed, 19 insertions(+), 2 deletions(-)
Index: libsass-3.3.2/src/eval.cpp
===================================================================
--- libsass-3.3.2.orig/src/eval.cpp
+++ libsass-3.3.2/src/eval.cpp
@@ -1513,8 +1513,28 @@ namespace Sass {
// the parser will look for a brace to end the selector
std::string result_str(s->contents()->perform(this)->perform(&to_string));
result_str = unquote(Util::rtrim(result_str)) + "{";
- Parser p = Parser::from_c_str(result_str.c_str(), ctx, s->pstate());
- return operator()(p.parse_selector_list(exp.block_stack.back()->is_root()));
+ char* temp_cstr = sass_copy_c_string(result_str.c_str());
+ ctx.strings.push_back(temp_cstr); // attach to context
+ Parser p = Parser::from_c_str(temp_cstr, ctx, s->pstate());
+ p.last_media_block = s->media_block();
+ bool root = exp.block_stack.back()->is_root();
+ Selector_List* sl = p.parse_selector_list(root);
+ auto vec_str_rend = ctx.strings.rend();
+ auto vec_str_rbegin = ctx.strings.rbegin();
+ // remove the first item searching from the back
+ // we cannot assume our item is still the last one
+ // order is not important, so we can optimize this
+ auto it = std::find(vec_str_rbegin, vec_str_rend, temp_cstr);
+ // undefined behavior if not found!
+ if (it != vec_str_rend) {
+ // overwrite with last item
+ *it = ctx.strings.back();
+ // remove last one from vector
+ ctx.strings.pop_back();
+ // free temporary copy
+ free(temp_cstr);
+ }
+ return operator()(sl);
}
Expression* Eval::operator()(Parent_Selector* p)