mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
ossfuzz: Fixes buggy generation of duplicate case literals
This commit is contained in:
parent
bdbe1e55b3
commit
68b7f40184
@ -31,7 +31,7 @@ string ProtoConverter::createHex(string const& _hexBytes) const
|
||||
});
|
||||
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())
|
||||
tmp = "1";
|
||||
return tmp;
|
||||
@ -50,6 +50,41 @@ string ProtoConverter::createAlphaNum(string const& _strBytes) const
|
||||
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)
|
||||
{
|
||||
switch (_x.literal_oneof_case())
|
||||
@ -319,21 +354,31 @@ void ProtoConverter::visit(ForStmt const& _x)
|
||||
|
||||
void ProtoConverter::visit(CaseStmt const& _x)
|
||||
{
|
||||
m_output << "case ";
|
||||
visit(_x.case_lit());
|
||||
m_output << " ";
|
||||
visit(_x.case_block());
|
||||
// Silently ignore duplicate case literals
|
||||
if (isCaseLiteralUnique(_x.case_lit()))
|
||||
{
|
||||
m_output << "case ";
|
||||
visit(_x.case_lit());
|
||||
m_output << " ";
|
||||
visit(_x.case_block());
|
||||
}
|
||||
}
|
||||
|
||||
void ProtoConverter::visit(SwitchStmt const& _x)
|
||||
{
|
||||
if (_x.case_stmt_size() > 0 || _x.has_default_block())
|
||||
{
|
||||
std::set<dev::u256> s;
|
||||
m_switchLiteralSetPerScope.push(s);
|
||||
m_output << "switch ";
|
||||
visit(_x.switch_expr());
|
||||
m_output << "\n";
|
||||
|
||||
for (auto const& caseStmt: _x.case_stmt())
|
||||
visit(caseStmt);
|
||||
|
||||
m_switchLiteralSetPerScope.pop();
|
||||
|
||||
if (_x.has_default_block())
|
||||
{
|
||||
m_output << "default ";
|
||||
|
@ -21,8 +21,11 @@
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <set>
|
||||
|
||||
#include <test/tools/ossfuzz/yulProto.pb.h>
|
||||
#include <libdevcore/Common.h>
|
||||
#include <libdevcore/FixedHash.h>
|
||||
|
||||
namespace yul
|
||||
{
|
||||
@ -68,12 +71,14 @@ private:
|
||||
|
||||
std::string createHex(std::string const& _hexBytes) const;
|
||||
std::string createAlphaNum(std::string const& _strBytes) const;
|
||||
bool isCaseLiteralUnique(Literal const&);
|
||||
|
||||
std::ostringstream m_output;
|
||||
std::stack<uint8_t> m_numVarsPerScope;
|
||||
int32_t m_numLiveVars;
|
||||
int32_t m_numNestedForLoops;
|
||||
std::stack<bool> m_inForScope;
|
||||
std::stack<std::set<dev::u256>> m_switchLiteralSetPerScope;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user