Skip to content

Commit 66fe16d

Browse files
authored
Improve Windows support (#248)
* utils: npm: fix path detection on Windows Windows will throw ValueError and not OSError if the path is too long pathobj = WindowsPath('{"compilation_units": {"/home/monty/tob/tools/slither/tests/ast-parsing/function-0.6.0.sol": {"compiler":...unction abstractFunc2() public virtual override(C6) {}/n function abstractFunc3() public virtual override {}/n}"}}') args = () @functools.wraps(strfunc) def wrapped(pathobj, *args): > return strfunc(str(pathobj), *args) E ValueError: stat: path too long for Windows c:\hostedtoolcache\windows\python\3.6.8\x64\lib\pathlib.py:387: ValueError * platform: archive: fix path checking on Windows Windows may throw an exception if the path is too long, which is the case when the string is not really a path. Catch it and try decoding the JSON in that case. * platform: *: fix command execution on Windows Some of the command executions could fail on Windows with errors such as the following: FileNotFoundError: [WinError 2] The system cannot find the file specified This is because the program name used in the command (e.g. "npm") is unqualified, and PATH lookup is not performed on Windows when `shell=False` is used. We can avoid this problem by converting the executable name to a fully-qualified path by using `shutil.which` and passing it as `executable` on the `Popen` call. * utils: naming: use POSIX-style paths for relative paths When looking up full paths, Windows-style paths may show up, but standardize on using POSIX-style paths for everything else. * platform: solc: remove extra prints These were introduced in bb594de ("upgrade pylint and black for super-linter v4") and currently break Slither's tests, which expect a certain output. * workflows: ci: disable embark It is currently broken, and tries to pull a repository via git:// which GH Actions now blocks.
1 parent e7a0c72 commit 66fe16d

File tree

15 files changed

+114
-25
lines changed

15 files changed

+114
-25
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ jobs:
1616
strategy:
1717
matrix:
1818
type: ["solc", "truffle", "embark", "etherlime", "brownie", "waffle", "buidler", "hardhat"]
19+
exclude:
20+
# Currently broken, tries to pull git:// which is blocked by GH
21+
- type: embark
1922
steps:
2023
- uses: actions/checkout@v1
2124
- name: Set up Python 3.6

crytic_compile/platform/archive.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,16 @@ def compile(self, crytic_compile: "CryticCompile", **_kwargs: str) -> None:
7777
# pylint: disable=import-outside-toplevel
7878
from crytic_compile.crytic_compile import get_platforms
7979

80-
if isinstance(self._target, str) and os.path.isfile(self._target):
81-
with open(self._target, encoding="utf8") as f_target:
82-
loaded_json = json.load(f_target)
83-
else:
80+
try:
81+
if isinstance(self._target, str) and os.path.isfile(self._target):
82+
with open(self._target, encoding="utf8") as f_target:
83+
loaded_json = json.load(f_target)
84+
else:
85+
loaded_json = json.loads(self._target)
86+
except (OSError, ValueError):
87+
# Can happen if the target is a very large string, isfile will throw an exception
8488
loaded_json = json.loads(self._target)
89+
8590
(underlying_type, unit_tests) = standard.load_from_compile(crytic_compile, loaded_json)
8691
underlying_type = TypePlatform(underlying_type)
8792
platforms: List[Type[AbstractPlatform]] = get_platforms()

crytic_compile/platform/brownie.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import json
55
import logging
66
import os
7+
import shutil
78
import subprocess
89
from pathlib import Path
910
from typing import TYPE_CHECKING, Dict, List
@@ -54,7 +55,11 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
5455
cmd = base_cmd + ["compile"]
5556
try:
5657
with subprocess.Popen(
57-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self._target
58+
cmd,
59+
stdout=subprocess.PIPE,
60+
stderr=subprocess.PIPE,
61+
cwd=self._target,
62+
executable=shutil.which(cmd[0]),
5863
) as process:
5964
stdout_bytes, stderr_bytes = process.communicate()
6065
stdout, stderr = (

crytic_compile/platform/buidler.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import json
55
import logging
66
import os
7+
import shutil
78
import subprocess
89
from pathlib import Path
910
from typing import TYPE_CHECKING, List, Tuple
@@ -70,7 +71,11 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
7071
)
7172

7273
with subprocess.Popen(
73-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self._target
74+
cmd,
75+
stdout=subprocess.PIPE,
76+
stderr=subprocess.PIPE,
77+
cwd=self._target,
78+
executable=shutil.which(cmd[0]),
7479
) as process:
7580

7681
stdout_bytes, stderr_bytes = process.communicate()

crytic_compile/platform/dapp.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import logging
88
import os
99
import re
10+
import shutil
1011
import subprocess
1112
from pathlib import Path
1213

@@ -176,7 +177,11 @@ def _run_dapp(target: str) -> None:
176177

177178
try:
178179
with subprocess.Popen(
179-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target
180+
cmd,
181+
stdout=subprocess.PIPE,
182+
stderr=subprocess.PIPE,
183+
cwd=target,
184+
executable=shutil.which(cmd[0]),
180185
) as process:
181186
_, _ = process.communicate()
182187
except OSError as error:

crytic_compile/platform/embark.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import json
66
import logging
77
import os
8+
import shutil
89
import subprocess
910
from pathlib import Path
1011
from typing import TYPE_CHECKING, List
@@ -64,7 +65,9 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
6465
if write_embark_json:
6566
try:
6667
with subprocess.Popen(
67-
["npm", "install", plugin_name], cwd=self._target
68+
["npm", "install", plugin_name],
69+
cwd=self._target,
70+
executable=shutil.which("npm"),
6871
) as process:
6972
_, stderr = process.communicate()
7073
with open(
@@ -91,7 +94,11 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
9194
cmd = ["npx"] + cmd
9295
# pylint: disable=consider-using-with
9396
process = subprocess.Popen(
94-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self._target
97+
cmd,
98+
stdout=subprocess.PIPE,
99+
stderr=subprocess.PIPE,
100+
cwd=self._target,
101+
executable=shutil.which(cmd[0]),
95102
)
96103
except OSError as error:
97104
# pylint: disable=raise-missing-from

crytic_compile/platform/etherlime.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import logging
88
import os
99
import re
10+
import shutil
1011
import subprocess
1112
from pathlib import Path
1213
from typing import TYPE_CHECKING, List, Optional, Any
@@ -48,7 +49,11 @@ def _run_etherlime(target: str, npx_disable: bool, compile_arguments: Optional[s
4849

4950
try:
5051
with subprocess.Popen(
51-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=target
52+
cmd,
53+
stdout=subprocess.PIPE,
54+
stderr=subprocess.PIPE,
55+
cwd=target,
56+
executable=shutil.which(cmd[0]),
5257
) as process:
5358
stdout_bytes, stderr_bytes = process.communicate()
5459
stdout, stderr = (

crytic_compile/platform/hardhat.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import json
55
import logging
66
import os
7+
import shutil
78
import subprocess
89
from pathlib import Path
910
from typing import TYPE_CHECKING, List
@@ -70,7 +71,11 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
7071
)
7172

7273
with subprocess.Popen(
73-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self._target
74+
cmd,
75+
stdout=subprocess.PIPE,
76+
stderr=subprocess.PIPE,
77+
cwd=self._target,
78+
executable=shutil.which(cmd[0]),
7479
) as process:
7580

7681
stdout_bytes, stderr_bytes = process.communicate()

crytic_compile/platform/solc.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import logging
66
import os
77
import re
8+
import shutil
89
import subprocess
910
from pathlib import Path
1011
from typing import TYPE_CHECKING, Dict, List, Optional, Union, Any
@@ -367,7 +368,11 @@ def get_version(solc: str, env: Optional[Dict[str, str]]) -> str:
367368
cmd = [solc, "--version"]
368369
try:
369370
with subprocess.Popen(
370-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env
371+
cmd,
372+
stdout=subprocess.PIPE,
373+
stderr=subprocess.PIPE,
374+
env=env,
375+
executable=shutil.which(cmd[0]),
371376
) as process:
372377
stdout_bytes, _ = process.communicate()
373378
stdout = stdout_bytes.decode() # convert bytestrings to unicode strings
@@ -376,7 +381,6 @@ def get_version(solc: str, env: Optional[Dict[str, str]]) -> str:
376381
raise InvalidCompilation(f"Solidity version not found: {stdout}")
377382
return version[0]
378383
except OSError as error:
379-
print("get versions")
380384
# pylint: disable=raise-missing-from
381385
raise InvalidCompilation(error)
382386

@@ -509,13 +513,21 @@ def _run_solc(
509513
# pylint: disable=consider-using-with
510514
if env:
511515
process = subprocess.Popen(
512-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, **additional_kwargs
516+
cmd,
517+
stdout=subprocess.PIPE,
518+
stderr=subprocess.PIPE,
519+
executable=shutil.which(cmd[0]),
520+
env=env,
521+
**additional_kwargs,
513522
)
514523
else:
515524
process = subprocess.Popen(
516-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **additional_kwargs
525+
cmd,
526+
stdout=subprocess.PIPE,
527+
stderr=subprocess.PIPE,
528+
executable=shutil.which(cmd[0]),
529+
**additional_kwargs,
517530
)
518-
print(cmd)
519531
except OSError as error:
520532
# pylint: disable=raise-missing-from
521533
raise InvalidCompilation(error)

crytic_compile/platform/solc_standard_json.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import json
55
import logging
66
import os
7+
import shutil
78
import subprocess
89
from typing import TYPE_CHECKING, Dict, List, Optional, Union, Any
910

@@ -146,6 +147,7 @@ def run_solc_standard_json(
146147
stdout=subprocess.PIPE,
147148
stderr=subprocess.PIPE,
148149
env=env,
150+
executable=shutil.which(cmd[0]),
149151
**additional_kwargs,
150152
) as process:
151153

0 commit comments

Comments
 (0)