solidity
solidity copied to clipboard
Inconsistent library address validations between CLI and Standard JSON
Checks applied to the value of --library option in CLI are not exactly the same as the ones for libraries in Standard JSON. For example only CLI checks address checksum. The validations should be reviewed and unified.
@cameel i want to take up this issue. I have builded up the solidity compiler on in my local environment and have successfully run all the test. Please guide me how can i solve this issue.
Sure. The problem is that checks in this part of CommandLineInterface::parseLibraryOption():
https://github.com/ethereum/solidity/blob/09578e7e22326ed60cb696685d18981f629cf075/solc/CommandLineInterface.cpp#L678-L748
and this one in StandardCompiler::parseInput():
https://github.com/ethereum/solidity/blob/09578e7e22326ed60cb696685d18981f629cf075/libsolidity/interface/StandardCompiler.cpp#L836-L871
are not the same. In particular:
- CLI checks address checksum but Standard JSON does not.
- CLI checks if the address is empty but Standard JSON does not. This check is redundant because we still check address length later but if it's there, it should be in both places.
- The checks for invalid characters are different (one uses
fromHex(), the other relies onh160constructor throwing exceptions). They are probably equivalent but there's really no reason for them not to be identical.
So the idea would be to make these checks as close as possible. I think it would be best to extract the validation into a single function called from both places.
The PR should include at least minimal commandline tests covering these new cases (unless they're already covered - please check). Here are some of the existing tests:
- https://github.com/ethereum/solidity/tree/develop/test/cmdlineTests/linking_standard_solidity/
- https://github.com/ethereum/solidity/tree/develop/test/cmdlineTests/linking_solidity/
There are more in subdirectories starting with linking_.
Note that soltest does not execute these tests. There's a separate script for running them: test/cmdlineTests.sh.
We also have tests covering this code in test/libsolidity/StandardCompiler.cpp but these are more suitable if you actually want to check the results in some more complex way. For just testing the error message command-line tests should be enough.
Also, there's another issue that's related to this: #10298. You might want to take it once you fix this one.
One more thing: there's a pending refactor that's likely to be merged into develop very soon: #11518. It moves the part I mentioned to CommandLineParser.cpp. You might want to start your branch already on top of it if you want to avoid rebasing it later.
I wonder if we should target the breaking branch for this.
Good point. Do we consider changes like that breaking? Technically it will now no longer be possible to use a library address with invalid checksum in Standard JSON, though we could also consider the lack of this check a bug.
The thing is that if we require checksums, we require the "caller" to include the full keccak algorithm as a dependency. Does it create an error or a warning?
In any case, @aaroosh-07 don't be discouraged by this discussion, we certainly want the feature, the question is just which version it should land in, but you can already start working on it regardless of that.
Well, solc-js already depends on it (js-sha3) so JS tools have that dependency already unless they go out of their way to use the compiler binary directly. Also looks like web3.js, whch a lot of them use depends on @ethersproject/keccak256. Might be a bigger problem for tools that use CLI with --standard-json (Brownie, dapp-tools) but they still usually let you download the compiler so they likely already have a way to verify keccak checksums (we only added SHA256 for binaries very recently).
Does it create an error or a warning?
It's an error:
if (!passesAddressChecksum(addrString, false))
{
serr() << "Invalid checksum on address for library \"" << libName << "\": " << addrString << endl;
serr() << "The correct checksum is " << getChecksummedAddress(addrString) << endl;
return false;
}
But it would not be hard to change it to a warning. Might actually be the best solution since it does not introduce any backwards-compatibility issues.
If the recommended checksum is not too hard to parse, it may be a good solution for a caller that does not have a keccak library to just iterate.
okay I'm on to this issue @cameel @chriseth
To solve this issue, I have to add checks which are not present in standard complier but present in commandLineInterface
Am I understanding the issue properly?
Yes.
But also please try to extract the common parts of this code into a function that we can reuse in both places. The function could take the address as a string, verify it's a valid and return it as h160. If it's not valid it should return an error message (either by throwing an exception or as a part of the result - you could use Result<h160> type for that).
progress till now
- added test for empty string in
standardcompiler.cpp - added test for checking address checksum in
standardcompiler.cpp
Had internal examinations past three days because of which had slow progress.
@aaroosh-07 How is it going? Do you need any help with the implementation?
sorry @cameel because of my university examinations going on, I have made not much progress on this issue.
the exceptions throwed by constructor h160 to check for address, is being used at multiply places in the file standard compiler.cpp so should I leave it as is?
No worries. Take your time. Just checking if you're still on it or if the task should be marked as available for someone else to take.
the exceptions throwed by constructor
h160to check for address, is being used at multiply places in the filestandard compiler.cppso should I leave it as is?
Either way is ok, just make sure that the same mechanism is used in both places. If you leave exceptions in StandardCompiler.cpp then just use them in CommandLineParser.cpp too.
Hi everyone, I am new to coding and open source, how can I contribute here? I have beginner knowledge of C & C++.
Any help would be highly appreciated.
Thanks & Regards