From b463ce94b81891a6ffaf75847a964ceb037708e3 Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Mon, 10 Aug 2015 10:19:00 +0100 Subject: [PATCH] Fixes some hidden NULL pointer dereferencing. 'specMap' parameter can sometimes be NULL (when not in '-c' mode). In code it was dereferenced before the check for '-c', but due to compiler optimizations this was never revealed. I found the bug while trying to measure the size of 'specMap' before the check (caught segfault). Fixed by moving the check prior to dereferencing. --- re2c/src/codegen/emit_dfa.cc | 89 ++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/re2c/src/codegen/emit_dfa.cc b/re2c/src/codegen/emit_dfa.cc index 11653a34..ad701021 100644 --- a/re2c/src/codegen/emit_dfa.cc +++ b/re2c/src/codegen/emit_dfa.cc @@ -128,7 +128,7 @@ void DFA::emit(Output & output, uint32_t& ind, const RegExpMap* specMap, const s else if ((!fFlag && o.get_used_yyaccept ()) || (!fFlag && bEmitYYCh) || (bFlag && !cFlag && BitMap::first) - || (cFlag && !bWroteCondCheck && gFlag && !specMap->empty()) + || (cFlag && !bWroteCondCheck && gFlag && specMap) || (fFlag && !bWroteGetState && gFlag) ) { @@ -159,7 +159,10 @@ void DFA::emit(Output & output, uint32_t& ind, const RegExpMap* specMap, const s } if (bProlog) { - genCondTable(o, ind, *specMap); + if (cFlag && !bWroteCondCheck && gFlag && specMap) + { + genCondTable(o, ind, *specMap); + } o.insert_state_goto (ind); if (cFlag && !DFlag) { @@ -169,7 +172,10 @@ void DFA::emit(Output & output, uint32_t& ind, const RegExpMap* specMap, const s } } o.write_user_start_label (); - genCondGoto(o, ind, *specMap); + if (cFlag && !bWroteCondCheck && specMap) + { + genCondGoto(o, ind, *specMap); + } } if (cFlag && !condName.empty()) @@ -236,23 +242,21 @@ void DFA::emit(Output & output, uint32_t& ind, const RegExpMap* specMap, const s void genCondTable(OutputFile & o, uint32_t ind, const RegExpMap& specMap) { - if (cFlag && !bWroteCondCheck && gFlag && specMap.size()) - { - RegExpIndices vCondList(specMap.size()); + const uint32_t specMap_size = static_cast (specMap.size ()); + RegExpIndices vCondList(specMap_size); - for(RegExpMap::const_iterator itSpec = specMap.begin(); itSpec != specMap.end(); ++itSpec) - { - vCondList[itSpec->second.first] = itSpec->first; - } + for(RegExpMap::const_iterator itSpec = specMap.begin(); itSpec != specMap.end(); ++itSpec) + { + vCondList[itSpec->second.first] = itSpec->first; + } - o << indent(ind++) << "static void *" << mapCodeName["yyctable"] << "[" << specMap.size() << "] = {\n"; + o << indent(ind++) << "static void *" << mapCodeName["yyctable"] << "[" << specMap_size << "] = {\n"; - for(RegExpIndices::const_iterator it = vCondList.begin(); it != vCondList.end(); ++it) - { - o << indent(ind) << "&&" << condPrefix << *it << ",\n"; - } - o << indent(--ind) << "};\n"; + for(RegExpIndices::const_iterator it = vCondList.begin(); it != vCondList.end(); ++it) + { + o << indent(ind) << "&&" << condPrefix << *it << ",\n"; } + o << indent(--ind) << "};\n"; } void genCondGotoSub(OutputFile & o, uint32_t ind, RegExpIndices& vCondList, uint32_t cMin, uint32_t cMax) @@ -275,44 +279,41 @@ void genCondGotoSub(OutputFile & o, uint32_t ind, RegExpIndices& vCondList, uint void genCondGoto(OutputFile & o, uint32_t ind, const RegExpMap& specMap) { - if (cFlag && !bWroteCondCheck && specMap.size()) + if (gFlag) { - if (gFlag) - { - o << indent(ind) << "goto *" << mapCodeName["yyctable"] << "[" << genGetCondition() << "];\n"; - } - else + o << indent(ind) << "goto *" << mapCodeName["yyctable"] << "[" << genGetCondition() << "];\n"; + } + else + { + if (sFlag) { - if (sFlag) + RegExpIndices vCondList(specMap.size()); + + for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) { - RegExpIndices vCondList(specMap.size()); - - for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) - { - vCondList[it->second.first] = it->first; - } - genCondGotoSub(o, ind, vCondList, 0, vCondList.size() - 1); + vCondList[it->second.first] = it->first; } - else if (DFlag) + genCondGotoSub(o, ind, vCondList, 0, static_cast (vCondList.size()) - 1); + } + else if (DFlag) + { + for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) { - for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) - { - o << "0 -> " << it->first << " [label=\"state=" << it->first << "\"]\n"; - } + o << "0 -> " << it->first << " [label=\"state=" << it->first << "\"]\n"; } - else + } + else + { + o << indent(ind) << "switch (" << genGetCondition() << ") {\n"; + + for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) { - o << indent(ind) << "switch (" << genGetCondition() << ") {\n"; - - for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) - { - o << indent(ind) << "case " << condEnumPrefix << it->first << ": goto " << condPrefix << it->first << ";\n"; - } - o << indent(ind) << "}\n"; + o << indent(ind) << "case " << condEnumPrefix << it->first << ": goto " << condPrefix << it->first << ";\n"; } + o << indent(ind) << "}\n"; } - bWroteCondCheck = true; } + bWroteCondCheck = true; } void genTypes(Output & output, const RegExpMap& specMap) -- 2.40.0