mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6539 from ethereum/fix-dup-case-literals
ossfuzz: Fixes buggy generation of duplicate case literals
This commit is contained in:
commit
f8b1326712
@ -31,7 +31,7 @@ string ProtoConverter::createHex(string const& _hexBytes) const
|
|||||||
});
|
});
|
||||||
tmp = tmp.substr(0, 64);
|
tmp = tmp.substr(0, 64);
|
||||||
}
|
}
|
||||||
// We need this awkward if case hex literals cannot be empty.
|
// We need this awkward if case because hex literals cannot be empty.
|
||||||
if (tmp.empty())
|
if (tmp.empty())
|
||||||
tmp = "1";
|
tmp = "1";
|
||||||
return tmp;
|
return tmp;
|
||||||
@ -50,6 +50,41 @@ string ProtoConverter::createAlphaNum(string const& _strBytes) const
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProtoConverter::isCaseLiteralUnique(Literal const& _x)
|
||||||
|
{
|
||||||
|
std::string tmp;
|
||||||
|
bool isUnique = false;
|
||||||
|
bool isEmptyString = false;
|
||||||
|
switch (_x.literal_oneof_case())
|
||||||
|
{
|
||||||
|
case Literal::kIntval:
|
||||||
|
tmp = std::to_string(_x.intval());
|
||||||
|
break;
|
||||||
|
case Literal::kHexval:
|
||||||
|
tmp = "0x" + createHex(_x.hexval());
|
||||||
|
break;
|
||||||
|
case Literal::kStrval:
|
||||||
|
tmp = createAlphaNum(_x.strval());
|
||||||
|
if (tmp.empty())
|
||||||
|
{
|
||||||
|
isEmptyString = true;
|
||||||
|
tmp = std::to_string(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tmp = "\"" + tmp + "\"";
|
||||||
|
break;
|
||||||
|
case Literal::LITERAL_ONEOF_NOT_SET:
|
||||||
|
tmp = std::to_string(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!_x.has_strval() || isEmptyString)
|
||||||
|
isUnique = m_switchLiteralSetPerScope.top().insert(dev::u256(tmp)).second;
|
||||||
|
else
|
||||||
|
isUnique = m_switchLiteralSetPerScope.top().insert(
|
||||||
|
dev::u256(dev::h256(tmp, dev::h256::FromBinary, dev::h256::AlignLeft))).second;
|
||||||
|
return isUnique;
|
||||||
|
}
|
||||||
|
|
||||||
void ProtoConverter::visit(Literal const& _x)
|
void ProtoConverter::visit(Literal const& _x)
|
||||||
{
|
{
|
||||||
switch (_x.literal_oneof_case())
|
switch (_x.literal_oneof_case())
|
||||||
@ -319,21 +354,31 @@ void ProtoConverter::visit(ForStmt const& _x)
|
|||||||
|
|
||||||
void ProtoConverter::visit(CaseStmt const& _x)
|
void ProtoConverter::visit(CaseStmt const& _x)
|
||||||
{
|
{
|
||||||
m_output << "case ";
|
// Silently ignore duplicate case literals
|
||||||
visit(_x.case_lit());
|
if (isCaseLiteralUnique(_x.case_lit()))
|
||||||
m_output << " ";
|
{
|
||||||
visit(_x.case_block());
|
m_output << "case ";
|
||||||
|
visit(_x.case_lit());
|
||||||
|
m_output << " ";
|
||||||
|
visit(_x.case_block());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::visit(SwitchStmt const& _x)
|
void ProtoConverter::visit(SwitchStmt const& _x)
|
||||||
{
|
{
|
||||||
if (_x.case_stmt_size() > 0 || _x.has_default_block())
|
if (_x.case_stmt_size() > 0 || _x.has_default_block())
|
||||||
{
|
{
|
||||||
|
std::set<dev::u256> s;
|
||||||
|
m_switchLiteralSetPerScope.push(s);
|
||||||
m_output << "switch ";
|
m_output << "switch ";
|
||||||
visit(_x.switch_expr());
|
visit(_x.switch_expr());
|
||||||
m_output << "\n";
|
m_output << "\n";
|
||||||
|
|
||||||
for (auto const& caseStmt: _x.case_stmt())
|
for (auto const& caseStmt: _x.case_stmt())
|
||||||
visit(caseStmt);
|
visit(caseStmt);
|
||||||
|
|
||||||
|
m_switchLiteralSetPerScope.pop();
|
||||||
|
|
||||||
if (_x.has_default_block())
|
if (_x.has_default_block())
|
||||||
{
|
{
|
||||||
m_output << "default ";
|
m_output << "default ";
|
||||||
|
@ -21,8 +21,11 @@
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include <test/tools/ossfuzz/yulProto.pb.h>
|
#include <test/tools/ossfuzz/yulProto.pb.h>
|
||||||
|
#include <libdevcore/Common.h>
|
||||||
|
#include <libdevcore/FixedHash.h>
|
||||||
|
|
||||||
namespace yul
|
namespace yul
|
||||||
{
|
{
|
||||||
@ -68,12 +71,14 @@ private:
|
|||||||
|
|
||||||
std::string createHex(std::string const& _hexBytes) const;
|
std::string createHex(std::string const& _hexBytes) const;
|
||||||
std::string createAlphaNum(std::string const& _strBytes) const;
|
std::string createAlphaNum(std::string const& _strBytes) const;
|
||||||
|
bool isCaseLiteralUnique(Literal const&);
|
||||||
|
|
||||||
std::ostringstream m_output;
|
std::ostringstream m_output;
|
||||||
std::stack<uint8_t> m_numVarsPerScope;
|
std::stack<uint8_t> m_numVarsPerScope;
|
||||||
int32_t m_numLiveVars;
|
int32_t m_numLiveVars;
|
||||||
int32_t m_numNestedForLoops;
|
int32_t m_numNestedForLoops;
|
||||||
std::stack<bool> m_inForScope;
|
std::stack<bool> m_inForScope;
|
||||||
|
std::stack<std::set<dev::u256>> m_switchLiteralSetPerScope;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user