mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Improves address literal checksum error message
This commit is contained in:
parent
2927ce0bd4
commit
8a6692b2cf
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
Features:
|
Features:
|
||||||
* Syntax Checker: Turn the usage of ``callcode`` into an error as experimental 0.5.0 feature.
|
* Syntax Checker: Turn the usage of ``callcode`` into an error as experimental 0.5.0 feature.
|
||||||
|
* Type Checker: Improve address checksum warning.
|
||||||
* Type Checker: More detailed errors for invalid array lengths (such as division by zero).
|
* Type Checker: More detailed errors for invalid array lengths (such as division by zero).
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
@ -86,20 +86,23 @@ bool dev::passesAddressChecksum(string const& _str, bool _strict)
|
|||||||
))
|
))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
return _str == dev::getChecksummedAddress(_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
string dev::getChecksummedAddress(string const& _addr)
|
||||||
|
{
|
||||||
|
string s = _addr.substr(0, 2) == "0x" ? _addr.substr(2) : _addr;
|
||||||
h256 hash = keccak256(boost::algorithm::to_lower_copy(s, std::locale::classic()));
|
h256 hash = keccak256(boost::algorithm::to_lower_copy(s, std::locale::classic()));
|
||||||
for (size_t i = 0; i < 40; ++i)
|
string ret = "0x";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < s.length(); ++i)
|
||||||
{
|
{
|
||||||
char addressCharacter = s[i];
|
char addressCharacter = s[i];
|
||||||
bool lowerCase;
|
|
||||||
if ('a' <= addressCharacter && addressCharacter <= 'f')
|
|
||||||
lowerCase = true;
|
|
||||||
else if ('A' <= addressCharacter && addressCharacter <= 'F')
|
|
||||||
lowerCase = false;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
unsigned nibble = (unsigned(hash[i / 2]) >> (4 * (1 - (i % 2)))) & 0xf;
|
unsigned nibble = (unsigned(hash[i / 2]) >> (4 * (1 - (i % 2)))) & 0xf;
|
||||||
if ((nibble >= 8) == lowerCase)
|
if (nibble >= 8)
|
||||||
return false;
|
ret += toupper(addressCharacter);
|
||||||
|
else
|
||||||
|
ret += tolower(addressCharacter);
|
||||||
}
|
}
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -209,4 +209,8 @@ bool contains(T const& _t, V const& _v)
|
|||||||
/// are considered valid.
|
/// are considered valid.
|
||||||
bool passesAddressChecksum(std::string const& _str, bool _strict);
|
bool passesAddressChecksum(std::string const& _str, bool _strict);
|
||||||
|
|
||||||
|
/// @returns the checksummed version of an address
|
||||||
|
/// @param hex strings that look like an address
|
||||||
|
std::string getChecksummedAddress(std::string const& _addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1122,7 +1122,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
var.annotation().type->toString() +
|
var.annotation().type->toString() +
|
||||||
". Try converting to type " +
|
". Try converting to type " +
|
||||||
valueComponentType->mobileType()->toString() +
|
valueComponentType->mobileType()->toString() +
|
||||||
" or use an explicit conversion."
|
" or use an explicit conversion."
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
@ -1320,7 +1320,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
|
|||||||
_tuple.annotation().isPure = isPure;
|
_tuple.annotation().isPure = isPure;
|
||||||
if (_tuple.isInlineArray())
|
if (_tuple.isInlineArray())
|
||||||
{
|
{
|
||||||
if (!inlineArrayType)
|
if (!inlineArrayType)
|
||||||
m_errorReporter.fatalTypeError(_tuple.location(), "Unable to deduce common type for array elements.");
|
m_errorReporter.fatalTypeError(_tuple.location(), "Unable to deduce common type for array elements.");
|
||||||
_tuple.annotation().type = make_shared<ArrayType>(DataLocation::Memory, inlineArrayType, types.size());
|
_tuple.annotation().type = make_shared<ArrayType>(DataLocation::Memory, inlineArrayType, types.size());
|
||||||
}
|
}
|
||||||
@ -2000,7 +2000,9 @@ void TypeChecker::endVisit(Literal const& _literal)
|
|||||||
m_errorReporter.warning(
|
m_errorReporter.warning(
|
||||||
_literal.location(),
|
_literal.location(),
|
||||||
"This looks like an address but has an invalid checksum. "
|
"This looks like an address but has an invalid checksum. "
|
||||||
"If this is not used as an address, please prepend '00'."
|
"If this is not used as an address, please prepend '00'. "
|
||||||
|
"Correct checksummed address: '" + _literal.getChecksummedAddress() + "'. "
|
||||||
|
"For more information please see https://solidity.readthedocs.io/en/develop/types.html#address-literals"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!_literal.annotation().type)
|
if (!_literal.annotation().type)
|
||||||
|
@ -583,3 +583,9 @@ bool Literal::passesAddressChecksum() const
|
|||||||
solAssert(isHexNumber(), "Expected hex number");
|
solAssert(isHexNumber(), "Expected hex number");
|
||||||
return dev::passesAddressChecksum(value(), true);
|
return dev::passesAddressChecksum(value(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Literal::getChecksummedAddress() const
|
||||||
|
{
|
||||||
|
solAssert(isHexNumber(), "Expected hex number");
|
||||||
|
return dev::getChecksummedAddress(value());
|
||||||
|
}
|
||||||
|
@ -1613,6 +1613,8 @@ public:
|
|||||||
bool looksLikeAddress() const;
|
bool looksLikeAddress() const;
|
||||||
/// @returns true if it passes the address checksum test.
|
/// @returns true if it passes the address checksum test.
|
||||||
bool passesAddressChecksum() const;
|
bool passesAddressChecksum() const;
|
||||||
|
/// @returns the checksummed version of an address
|
||||||
|
std::string getChecksummedAddress() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value m_token;
|
Token::Value m_token;
|
||||||
|
Loading…
Reference in New Issue
Block a user