Backslash interpretation in relative import path resolution is platform-dependent
Discovered in #14554.
Our logic for resolving relative imports differs between platforms. Specifically, on Windows backslashes are treated as path separators while on Linux and macOS they are not.
This is happening at the stage where the compiler is calculating source unit names and these should be the same on all platforms because they're used for lookups in the compiler's VFS. If they differ, the same self-contained Standard JSON input may produce different bytecode on different platforms.
The cause is the use of boost::filesystem in our absolutePath(). Despite the name, this function operates on import/source unit names and not on filesystem paths. It should not be using a platform-aware library for resolving them.
Environment
- Compiler version: 0.8.21
Steps to Reproduce
This Standard JSON input will produce different versions of contract C between Windows and Linux:
{
"language": "Solidity",
"sources": {
"x\\y.sol": {
"content": "import \"./a\\\\b.sol\"; contract C { function f() public pure returns (string memory) { return answer(); } }"
},
"x/a/b.sol": {
"content": "function answer() pure returns (string memory) { return \"x\"; }"
},
"a\\b.sol": {
"content": "function answer() pure returns (string memory) { return \"y\"; }"
}
},
"settings": {"outputSelection": {"*": { "*": ["metadata", "evm.bytecode"]}}}
}
On Linux the releative import ./a\b.sol resolves into a\b.sol since \ is not treated as a path separator and x\y.solas a whole is treated as the importing file name. On Windows, however, the result is x/a/b.sol because both / and \ are seen as a path separators. x suddenly becomes a parent directory containing y.sol in the VFS. On Windows the separators also get normalized into /.
Due to this C.f() will call different implementations of answer() on Linux and on Windows. It will return "y" when compiled on Linux and "x" when compiled on Windows. This can be seen in the bytecode below: the Linux version contains
PUSH32 0x7900000000000000000000000000000000000000000000000000000000000000, while the Windows one has:
PUSH32 0x7800000000000000000000000000000000000000000000000000000000000000.
Diff of Windows and Linux output
@@ -17 +17 @@
-121565b60405180910390f35b606061005561005a565b905090565b60606040518060400160405280600181526020017f7900000000000
+121565b60405180910390f35b606061005561005a565b905090565b60606040518060400160405280600181526020017f7800000000000
@@ -21,2 +21,2 @@
-092915050565b5f6020820190508181035f83015261013981846100e9565b90509291505056fea2646970667358221220c0cc6bccf951a
-f448964dc4e18e144c1bfc183061c366905ba9035d9809c086e64736f6c63430008150033",
+092915050565b5f6020820190508181035f83015261013981846100e9565b90509291505056fea2646970667358221220dbb3b684a731d
+80b2de01eeb9438b9339384ad2c11e0e2e0c00f47cde39c2d2764736f6c63430008150033",
@@ -30 +30 @@
-MSTORE PUSH1 0x20 ADD PUSH32 0x7900000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PO
+MSTORE PUSH1 0x20 ADD PUSH32 0x7800000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PO
@@ -39,3 +39,3 @@
-POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xC0 0xCC PUSH12 0xCCF951AF448964DC4E18E144 0xC1 0
-xBF 0xC1 DUP4 MOD SHR CALLDATASIZE PUSH10 0x5BA9035D9809C086E64 PUSH20 0x6F6C634300081500330000000000000000000
-000 ",
+POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xDB 0xB3 0xB6 DUP5 0xA7 BALANCE 0xD8 SIGNEXTEND 0
+x2D 0xE0 0x1E 0xEB SWAP5 CODESIZE 0xB9 CALLER SWAP4 DUP5 0xAD 0x2C GT 0xE0 0xE2 0xE0 0xC0 0xF SELFBALANCE 0xCD
+ 0xE3 SWAP13 0x2D 0x27 PUSH5 0x736F6C6343 STOP ADDMOD ISZERO STOP CALLER ",
@@ -50,6 +50,6 @@
-ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"a\\\\b.sol\":{\"kecca
-k256\":\"0x9803f08da80a8f7a23f0b9dbe78de3fc5f77eb4f4377dfc8d8dc2d34a5b0bad5\",\"urls\":[\"bzz-raw://a580f08d01
-c9e12b41da658f14b23f62081e8a1058122d1ba1e0c472a9417078\",\"dweb:/ipfs/QmcEnSgpmmJAL4LymQjQ4GQ6kB1D2EJSfF7UEGGV
-8V37bj\"]},\"x\\\\y.sol\":{\"keccak256\":\"0x6808c0baa7142a29155780f26235635ced804595032b9164987bede378428845\
-",\"urls\":[\"bzz-raw://b63bfd44ee92a87a5c20602d842a0ef2c62b08672da449d7d16479e851e02a1b\",\"dweb:/ipfs/QmUvuj
-rz2zEF3K6ParEwuiXDiwGizTJ6PEbcTExMbJtZTX\"]}},\"version\":1}"
+ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"x/a/b.sol\":{\"keccak
+256\":\"0x2c855779a52cb058acdc005e46a12633f28438e851894d7697b969701671352b\",\"urls\":[\"bzz-raw://85f20913819
+f554cffa3b3a02411bb4250dbc94688c2a4e13ae5c1f9dfc8d628\",\"dweb:/ipfs/QmTUjFqqJ27xzB8xoknCYjb1QyKxdYinGPjrK8825
+tGVdE\"]},\"x\\\\y.sol\":{\"keccak256\":\"0x6808c0baa7142a29155780f26235635ced804595032b9164987bede378428845\"
+,\"urls\":[\"bzz-raw://b63bfd44ee92a87a5c20602d842a0ef2c62b08672da449d7d16479e851e02a1b\",\"dweb:/ipfs/QmUvujr
+z2zEF3K6ParEwuiXDiwGizTJ6PEbcTExMbJtZTX\"]}},\"version\":1}"
Full Windows output
{
"contracts":
{
"x\\y.sol":
{
"C":
{
"evm":
{
"bytecode":
{
"functionDebugData": {},
"generatedSources": [],
"linkReferences": {},
"object": "608060405234801561000f575f80fd5b506101778061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c806326121ff01461002d575b5f80fd5b61003561004b565b6040516100429190610121565b60405180910390f35b606061005561005a565b905090565b60606040518060400160405280600181526020017f7800000000000000000000000000000000000000000000000000000000000000815250905090565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156100ce5780820151818401526020810190506100b3565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6100f382610097565b6100fd81856100a1565b935061010d8185602086016100b1565b610116816100d9565b840191505092915050565b5f6020820190508181035f83015261013981846100e9565b90509291505056fea2646970667358221220dbb3b684a731d80b2de01eeb9438b9339384ad2c11e0e2e0c00f47cde39c2d2764736f6c63430008150033",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0xF JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH2 0x177 DUP1 PUSH2 0x1D PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0xF JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x29 JUMPI PUSH0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x26121FF0 EQ PUSH2 0x2D JUMPI JUMPDEST PUSH0 DUP1 REVERT JUMPDEST PUSH2 0x35 PUSH2 0x4B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x42 SWAP2 SWAP1 PUSH2 0x121 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH2 0x55 PUSH2 0x5A JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x7800000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH0 DUP2 MLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH0 DUP3 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xCE JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0xB3 JUMP JUMPDEST PUSH0 DUP5 DUP5 ADD MSTORE POP POP POP POP JUMP JUMPDEST PUSH0 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH0 PUSH2 0xF3 DUP3 PUSH2 0x97 JUMP JUMPDEST PUSH2 0xFD DUP2 DUP6 PUSH2 0xA1 JUMP JUMPDEST SWAP4 POP PUSH2 0x10D DUP2 DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0xB1 JUMP JUMPDEST PUSH2 0x116 DUP2 PUSH2 0xD9 JUMP JUMPDEST DUP5 ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH0 PUSH1 0x20 DUP3 ADD SWAP1 POP DUP2 DUP2 SUB PUSH0 DUP4 ADD MSTORE PUSH2 0x139 DUP2 DUP5 PUSH2 0xE9 JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xDB 0xB3 0xB6 DUP5 0xA7 BALANCE 0xD8 SIGNEXTEND 0x2D 0xE0 0x1E 0xEB SWAP5 CODESIZE 0xB9 CALLER SWAP4 DUP5 0xAD 0x2C GT 0xE0 0xE2 0xE0 0xC0 0xF SELFBALANCE 0xCD 0xE3 SWAP13 0x2D 0x27 PUSH5 0x736F6C6343 STOP ADDMOD ISZERO STOP CALLER ",
"sourceMap": "21:84:2:-:0;;;;;;;;;;;;;;;;;;;"
}
},
"metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"f\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"x\\\\y.sol\":\"C\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"x/a/b.sol\":{\"keccak256\":\"0x2c855779a52cb058acdc005e46a12633f28438e851894d7697b969701671352b\",\"urls\":[\"bzz-raw://85f20913819f554cffa3b3a02411bb4250dbc94688c2a4e13ae5c1f9dfc8d628\",\"dweb:/ipfs/QmTUjFqqJ27xzB8xoknCYjb1QyKxdYinGPjrK8825tGVdE\"]},\"x\\\\y.sol\":{\"keccak256\":\"0x6808c0baa7142a29155780f26235635ced804595032b9164987bede378428845\",\"urls\":[\"bzz-raw://b63bfd44ee92a87a5c20602d842a0ef2c62b08672da449d7d16479e851e02a1b\",\"dweb:/ipfs/QmUvujrz2zEF3K6ParEwuiXDiwGizTJ6PEbcTExMbJtZTX\"]}},\"version\":1}"
}
}
},
"errors":
[
{
"component": "general",
"errorCode": "1878",
"formattedMessage": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> a\\b.sol\n\n",
"message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "a\\b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "1878",
"formattedMessage": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> x/a/b.sol\n\n",
"message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x/a/b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "1878",
"formattedMessage": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> x\\y.sol\n\n",
"message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x\\y.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "3420",
"formattedMessage": "Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"\n--> a\\b.sol\n\n",
"message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "a\\b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "3420",
"formattedMessage": "Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"\n--> x/a/b.sol\n\n",
"message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x/a/b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "3420",
"formattedMessage": "Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"\n--> x\\y.sol\n\n",
"message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x\\y.sol",
"start": -1
},
"type": "Warning"
}
],
"sources":
{
"a\\b.sol":
{
"id": 0
},
"x/a/b.sol":
{
"id": 1
},
"x\\y.sol":
{
"id": 2
}
}
}
Full Linux output
{
"contracts":
{
"x\\y.sol":
{
"C":
{
"evm":
{
"bytecode":
{
"functionDebugData": {},
"generatedSources": [],
"linkReferences": {},
"object": "608060405234801561000f575f80fd5b506101778061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c806326121ff01461002d575b5f80fd5b61003561004b565b6040516100429190610121565b60405180910390f35b606061005561005a565b905090565b60606040518060400160405280600181526020017f7900000000000000000000000000000000000000000000000000000000000000815250905090565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156100ce5780820151818401526020810190506100b3565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6100f382610097565b6100fd81856100a1565b935061010d8185602086016100b1565b610116816100d9565b840191505092915050565b5f6020820190508181035f83015261013981846100e9565b90509291505056fea2646970667358221220c0cc6bccf951af448964dc4e18e144c1bfc183061c366905ba9035d9809c086e64736f6c63430008150033",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0xF JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH2 0x177 DUP1 PUSH2 0x1D PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0xF JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x29 JUMPI PUSH0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x26121FF0 EQ PUSH2 0x2D JUMPI JUMPDEST PUSH0 DUP1 REVERT JUMPDEST PUSH2 0x35 PUSH2 0x4B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x42 SWAP2 SWAP1 PUSH2 0x121 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH2 0x55 PUSH2 0x5A JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x1 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x7900000000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH0 DUP2 MLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH0 DUP3 DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xCE JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0xB3 JUMP JUMPDEST PUSH0 DUP5 DUP5 ADD MSTORE POP POP POP POP JUMP JUMPDEST PUSH0 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH0 PUSH2 0xF3 DUP3 PUSH2 0x97 JUMP JUMPDEST PUSH2 0xFD DUP2 DUP6 PUSH2 0xA1 JUMP JUMPDEST SWAP4 POP PUSH2 0x10D DUP2 DUP6 PUSH1 0x20 DUP7 ADD PUSH2 0xB1 JUMP JUMPDEST PUSH2 0x116 DUP2 PUSH2 0xD9 JUMP JUMPDEST DUP5 ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH0 PUSH1 0x20 DUP3 ADD SWAP1 POP DUP2 DUP2 SUB PUSH0 DUP4 ADD MSTORE PUSH2 0x139 DUP2 DUP5 PUSH2 0xE9 JUMP JUMPDEST SWAP1 POP SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xC0 0xCC PUSH12 0xCCF951AF448964DC4E18E144 0xC1 0xBF 0xC1 DUP4 MOD SHR CALLDATASIZE PUSH10 0x5BA9035D9809C086E64 PUSH20 0x6F6C634300081500330000000000000000000000 ",
"sourceMap": "21:84:2:-:0;;;;;;;;;;;;;;;;;;;"
}
},
"metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"f\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"x\\\\y.sol\":\"C\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"a\\\\b.sol\":{\"keccak256\":\"0x9803f08da80a8f7a23f0b9dbe78de3fc5f77eb4f4377dfc8d8dc2d34a5b0bad5\",\"urls\":[\"bzz-raw://a580f08d01c9e12b41da658f14b23f62081e8a1058122d1ba1e0c472a9417078\",\"dweb:/ipfs/QmcEnSgpmmJAL4LymQjQ4GQ6kB1D2EJSfF7UEGGV8V37bj\"]},\"x\\\\y.sol\":{\"keccak256\":\"0x6808c0baa7142a29155780f26235635ced804595032b9164987bede378428845\",\"urls\":[\"bzz-raw://b63bfd44ee92a87a5c20602d842a0ef2c62b08672da449d7d16479e851e02a1b\",\"dweb:/ipfs/QmUvujrz2zEF3K6ParEwuiXDiwGizTJ6PEbcTExMbJtZTX\"]}},\"version\":1}"
}
}
},
"errors":
[
{
"component": "general",
"errorCode": "1878",
"formattedMessage": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> a\\b.sol\n\n",
"message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "a\\b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "1878",
"formattedMessage": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> x/a/b.sol\n\n",
"message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x/a/b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "1878",
"formattedMessage": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> x\\y.sol\n\n",
"message": "SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x\\y.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "3420",
"formattedMessage": "Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"\n--> a\\b.sol\n\n",
"message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "a\\b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "3420",
"formattedMessage": "Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"\n--> x/a/b.sol\n\n",
"message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x/a/b.sol",
"start": -1
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "3420",
"formattedMessage": "Warning: Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"\n--> x\\y.sol\n\n",
"message": "Source file does not specify required compiler version! Consider adding \"pragma solidity ^0.8.21;\"",
"severity": "warning",
"sourceLocation":
{
"end": -1,
"file": "x\\y.sol",
"start": -1
},
"type": "Warning"
}
],
"sources":
{
"a\\b.sol":
{
"id": 0
},
"x/a/b.sol":
{
"id": 1
},
"x\\y.sol":
{
"id": 2
}
}
}
@kuzdogan Have you seen an example of this in the wild? I'd not expect one exactly like this, where things still compile on both platforms, but I think that a contract that was developed on Windows and compiles only there is a real possibility.
We wouldn't be able to catch a contract developed on Windows and only compiles on Windows because Sourcify runs on Linux but I can check for a specific case inside the repo.
When looking for weird path examples there were these:
browser/hopdong\.sol
browser/stakingTest \ .sol
project:/contracts/a`~!@#$%^&*()-=_+[]{}|\;:'",<>?ÿø±ö«»¿ð�~K�~X��[email protected]
Not sure if it helps
ok, none of them seems to be related to this but it's interesting to know that another plausible way for \ to appear in paths is botched escaping :)
I mean, actually it is somewhat related - I suspect that none of these contracts would compile on Windows if they contain relative imports. But yeah, that does not affect Sourcify.