From 69ece6da84ee50b2f2c4b61c151af394a7c26690 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Wed, 20 Mar 2024 11:03:27 -0500 Subject: [PATCH 1/2] fix: support aliases for NewContract operation --- slither/slithir/convert.py | 7 +++---- slither/slithir/operations/new_contract.py | 14 +++++++------- .../expressions/expression_parsing.py | 17 +++-------------- tests/e2e/solc_parsing/test_ast_parsing.py | 2 ++ .../aliasing/alias-symbol-NewContract.sol | 8 ++++++++ .../aliasing/alias-unit-NewContract.sol | 9 +++++++++ ...s-symbol-NewContract.sol-0.8.19-compact.zip | Bin 0 -> 2042 bytes ...ias-unit-NewContract.sol-0.8.19-compact.zip | Bin 0 -> 2017 bytes ...-symbol-NewContract.sol-0.8.19-compact.json | 6 ++++++ ...as-unit-NewContract.sol-0.8.19-compact.json | 6 ++++++ 10 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 tests/e2e/solc_parsing/test_data/aliasing/alias-symbol-NewContract.sol create mode 100644 tests/e2e/solc_parsing/test_data/aliasing/alias-unit-NewContract.sol create mode 100644 tests/e2e/solc_parsing/test_data/compile/aliasing/alias-symbol-NewContract.sol-0.8.19-compact.zip create mode 100644 tests/e2e/solc_parsing/test_data/compile/aliasing/alias-unit-NewContract.sol-0.8.19-compact.zip create mode 100644 tests/e2e/solc_parsing/test_data/expected/aliasing/alias-symbol-NewContract.sol-0.8.19-compact.json create mode 100644 tests/e2e/solc_parsing/test_data/expected/aliasing/alias-unit-NewContract.sol-0.8.19-compact.json diff --git a/slither/slithir/convert.py b/slither/slithir/convert.py index 170df8cba9..a89b0c3713 100644 --- a/slither/slithir/convert.py +++ b/slither/slithir/convert.py @@ -871,9 +871,7 @@ def propagate_types(ir: Operation, node: "Node"): # pylint: disable=too-many-lo elif isinstance(ir, NewArray): ir.lvalue.set_type(ir.array_type) elif isinstance(ir, NewContract): - contract = node.file_scope.get_contract_from_name(ir.contract_name) - assert contract - ir.lvalue.set_type(UserDefinedType(contract)) + ir.lvalue.set_type(ir.contract_name) elif isinstance(ir, NewElementaryType): ir.lvalue.set_type(ir.type) elif isinstance(ir, NewStructure): @@ -1164,7 +1162,7 @@ def extract_tmp_call(ins: TmpCall, contract: Optional[Contract]) -> Union[Call, return n if isinstance(ins.ori, TmpNewContract): - op = NewContract(Constant(ins.ori.contract_name), ins.lvalue) + op = NewContract(ins.ori.contract_name, ins.lvalue) op.set_expression(ins.expression) op.call_id = ins.call_id if ins.call_value: @@ -1719,6 +1717,7 @@ def convert_type_of_high_and_internal_level_call( Returns: Potential new IR """ + func = None if isinstance(ir, InternalCall): candidates: List[Function] diff --git a/slither/slithir/operations/new_contract.py b/slither/slithir/operations/new_contract.py index 9ed00b1ac0..928cbd0135 100644 --- a/slither/slithir/operations/new_contract.py +++ b/slither/slithir/operations/new_contract.py @@ -3,6 +3,7 @@ from slither.core.declarations import Function from slither.core.declarations.contract import Contract from slither.core.variables import Variable +from slither.core.solidity_types import UserDefinedType from slither.slithir.operations import Call, OperationWithLValue from slither.slithir.utils.utils import is_valid_lvalue from slither.slithir.variables.constant import Constant @@ -13,7 +14,7 @@ class NewContract(Call, OperationWithLValue): # pylint: disable=too-many-instance-attributes def __init__( self, - contract_name: Constant, + contract_name: UserDefinedType, lvalue: Union[TemporaryVariableSSA, TemporaryVariable], names: Optional[List[str]] = None, ) -> None: @@ -23,7 +24,9 @@ def __init__( For calls of the form f({argName1 : arg1, ...}), the names of parameters listed in call order. Otherwise, None. """ - assert isinstance(contract_name, Constant) + assert isinstance( + contract_name.type, Contract + ), f"contract_name is {contract_name} of type {type(contract_name)}" assert is_valid_lvalue(lvalue) super().__init__(names=names) self._contract_name = contract_name @@ -58,7 +61,7 @@ def call_salt(self, s): self._call_salt = s @property - def contract_name(self) -> Constant: + def contract_name(self) -> UserDefinedType: return self._contract_name @property @@ -69,10 +72,7 @@ def read(self) -> List[Any]: @property def contract_created(self) -> Contract: - contract_name = self.contract_name - contract_instance = self.node.file_scope.get_contract_from_name(contract_name) - assert contract_instance - return contract_instance + return self.contract_name.type ################################################################################### ################################################################################### diff --git a/slither/solc_parsing/expressions/expression_parsing.py b/slither/solc_parsing/expressions/expression_parsing.py index 4100d16ad7..4991984ff7 100644 --- a/slither/solc_parsing/expressions/expression_parsing.py +++ b/slither/solc_parsing/expressions/expression_parsing.py @@ -614,20 +614,9 @@ def parse_expression(expression: Dict, caller_context: CallerContextExpression) assert type_name[caller_context.get_key()] == "UserDefinedTypeName" - if is_compact_ast: - - # Changed introduced in Solidity 0.8 - # see https://github.com/crytic/slither/issues/794 - - # TODO explore more the changes introduced in 0.8 and the usage of pathNode/IdentifierPath - if "name" not in type_name: - assert "pathNode" in type_name and "name" in type_name["pathNode"] - contract_name = type_name["pathNode"]["name"] - else: - contract_name = type_name["name"] - else: - contract_name = type_name["attributes"]["name"] - new = NewContract(contract_name) + contract_type = parse_type(type_name, caller_context) + assert isinstance(contract_type, UserDefinedType) + new = NewContract(contract_type) new.set_offset(src, caller_context.compilation_unit) return new diff --git a/tests/e2e/solc_parsing/test_ast_parsing.py b/tests/e2e/solc_parsing/test_ast_parsing.py index 522d49cce6..96346bf368 100644 --- a/tests/e2e/solc_parsing/test_ast_parsing.py +++ b/tests/e2e/solc_parsing/test_ast_parsing.py @@ -467,6 +467,8 @@ def make_version(minor: int, patch_min: int, patch_max: int) -> List[str]: ), Test("user_defined_operators-0.8.19.sol", ["0.8.19"]), Test("aliasing/main.sol", ["0.8.19"]), + Test("aliasing/alias-unit-NewContract.sol", ["0.8.19"]), + Test("aliasing/alias-symbol-NewContract.sol", ["0.8.19"]), Test("type-aliases.sol", ["0.8.19"]), Test("enum-max-min.sol", ["0.8.19"]), Test("event-top-level.sol", ["0.8.22"]), diff --git a/tests/e2e/solc_parsing/test_data/aliasing/alias-symbol-NewContract.sol b/tests/e2e/solc_parsing/test_data/aliasing/alias-symbol-NewContract.sol new file mode 100644 index 0000000000..1f545461b4 --- /dev/null +++ b/tests/e2e/solc_parsing/test_data/aliasing/alias-symbol-NewContract.sol @@ -0,0 +1,8 @@ +import {MyContract as MyAliasedContract} from "./MyContract.sol"; + +contract Test { +MyAliasedContract c; + constructor() { + c = new MyAliasedContract(); + } +} diff --git a/tests/e2e/solc_parsing/test_data/aliasing/alias-unit-NewContract.sol b/tests/e2e/solc_parsing/test_data/aliasing/alias-unit-NewContract.sol new file mode 100644 index 0000000000..f46693d09f --- /dev/null +++ b/tests/e2e/solc_parsing/test_data/aliasing/alias-unit-NewContract.sol @@ -0,0 +1,9 @@ + +import "./MyContract.sol" as MyAliasedContract; + +contract Test { +MyAliasedContract.MyContract c; + constructor() { + c = new MyAliasedContract.MyContract(); + } +} \ No newline at end of file diff --git a/tests/e2e/solc_parsing/test_data/compile/aliasing/alias-symbol-NewContract.sol-0.8.19-compact.zip b/tests/e2e/solc_parsing/test_data/compile/aliasing/alias-symbol-NewContract.sol-0.8.19-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..b630fb8c4908a276b2fcf8d904d8210c308e6052 GIT binary patch literal 2042 zcmb8wX&}>$0|)S*W6oSli9{(6PoaiQG0YXq8m3S}!)QZuENX_yF=s-^)f6h{pFBde z%vqWvxi)enOp7^kl!u<4|NH-o|M&ai`|A7pV{a=YYzhbh(tw={$z}R+9OkSj0Ms1= zfHMF9VEysf5bcmV0iHyEZ8R>-f_Re@jP)Yvgb@8baJK`A!6XlCu-6TIC{BkELcA$1 z3P{2?@S>f9nN39_)K*BvsIP6R-Y8B`y`CWTHA6^7Q!5W1QlR_@DkbO~Ko}i5pR#FckE0aL z#IahJ18GIXUYl8H#feF%xcLjuWMXT!{6}XzspESVW$D=9Bg3?}6~yTZ{-^}prjyLK zXmxV8D3smzcm|XCso2(fF=fHoql~xZt#(@7feo(^f?gSu$#6F4FZkA0+Z`nF)ge&A zj_#tbcv6()UHn!%nYIq^-lzSFr7Qi*ZmyDW(Rmlsxa(;VnRMwzKCd2jCA|PDT5Psc zCY1FJ(6fUXh$wPHTla+g6t(6rcqc(*gihX3G4i>QZ}YTay(g-DD_oa%!DHRhrk@BF zx3Cwm(zlu%D_3BXW)kvp23~zoJ48rQa2Htc@fm=!_3Q=}+BvTU3bZw@_mNL&Cadv> zz+$pR6pf=Do)LicO@xRC&9v*3Fw+!UYA27gfX8LZ#%4pn4Y zpQWH1e*NCZMdS3V^GnxQL4pY7@8Ea?HcGp{qXd866~BKVOd zYcfdfZp<1rjN2U~rRc?QTMEdzdPU!*__dMP7tsC}_;4+(V((gmmHu`%Vh?mh!!PV% zO$f#UBDp!2pDm8Cm?uK$KCxa#sP)UIV4cg*+*eaVm+gi2awgN6 z5a|q`yu`+M{*wkY4K9|9l!u`v)!edndK8b>h*H1y=)1A}m>z9)h__1HoKx#gR`sQ? zYo6`=RoD1=DJ)h~860Yf9XroRzV+U6+b4)|jwa6tXUD6wY}jgTQBm<#sj|K&U4J$V zE4^xX*}ho*!lI~)VC|C^)m(!^>kB_31Dj0;QehuT+z{&h_9vl##b86)zW<$hvbcp9yW7 zXHUX`yEbmu%8#98KO`4VIqH{x?R_Nc4hb8F)_ThviQfAY?6Kf2?|s?&`QdOoWb86# z?4n6AJ=)UsulKud_2bklc} z=ud!a+pqM1y9T<&Gt$=_DjbT2+&(~z->0>iozFc~!&p)&>FXUno{D!%Bev{@l`QqC zmZafc=ICbE1_q_^Pr2e?fJ;s-ZJgIK2Vzam2iOPzdA?0xcq@pr*dWy=F^aD}n&Y@> zaT^#f+goVHR7I9-`*H6EzS|`22V3|F`OK`X#^P3_%_Sxf+o$bAuWLj=AjH^Jp@y=T6Or^)+jN8SUNMYVCx_24|UBG`Zy&HQW;qmtR z(UBeX6#A?|&Z(;z@czw<-RS%H4jD2ZZ8|^D;w!8)-!P{Ukz;K6lYY*3ejuq>@aCxE zmnNwgTuRipdU|rCpLEBM4Y{)$oha@Kda-(6`y@HJJC*lThtbXtoHsnsp57gCDFb|@ z?r7;88ujgC6zld;ejZskG*appiC-W4aDJssJZoxPl)6!eZ5L2QkPvPL?b32Nq5uwb4Y_diHEXK&j#TWt3`>LtwanowFWo4A*c@n{A5Qe3lfP(Ck}OnH44| zBAX<-hl|oH`<_?x1f@{AZ?TD9?(e-i7~jj-Kf8KoUcBSo+e~$+@>fhL;MMe zK08Odw#0@$zzYs`>UE%HW`LLKv0gy@rCWK86jh0 z-}bY{mk(kL;>HuKP(vQ7_+|n!^UFl@#<-|W?(?d;uPa)(O_O^zOoR*!0?u1r#(kc| zUfsRl$m7u_j7{g*2RI?wQk z#RaNil__QStJcNqyuGb}psCRRcKA2N{|!~(-}!%4wzma|{QDF5UH9J`|66zf_y^vO B(9Hk< literal 0 HcmV?d00001 diff --git a/tests/e2e/solc_parsing/test_data/compile/aliasing/alias-unit-NewContract.sol-0.8.19-compact.zip b/tests/e2e/solc_parsing/test_data/compile/aliasing/alias-unit-NewContract.sol-0.8.19-compact.zip new file mode 100644 index 0000000000000000000000000000000000000000..da511363567951259cbb5339e57a6a614a6bb07c GIT binary patch literal 2017 zcmb7_c|6mN1ING2=6Iy#jH1bvvgJst91XEYuGUkp&3!$Nq%AfqIWu=71~}k#7?MNv`gJp1wDNy%2sx0$x-I z3^)To6aW|{B>3p<=miw?b=4Xic-o4;q4rKGmU>me_}BoEC9CrTeK3}m>4F`&3qS)_ zWM-d0n`t~$jI;*Ryst5cv`im0Kq1uGaamDivWMluwgPB=2pJPG`*0~F!aAX;J=IHQ}|{!+?y1#WIq)U1~PXZMG0E;g3KabvC1iFtIp`Z zLLKzm-Y{EBETb(6w{jzG3n_Y=y4m4biC-)`P!&)xl*==WOAB}Fl|LH1sh_K!Z@uOX z67K9mgw=kU@tszO{DG7(_BYI9KF_(})!P%C{v4BZx5ZGP(>6^j93`G_cY}nRugCN$ zAapKJG2sn+K`q&%H7fq+Drtk6M3ujo_I^>AbT2FKs)dg%kZ1l+Eq)44|%Vfy|N=P!N9I(!e z_`I=mRCU#3t%P=`Z}un3A=t)4eFIhIPOUu7lmX9*XqR3cVMH*ZzR2Moe7IA9j=-)# zf0_KUSeAWj=UFPZwiQ06*ht8}=zY${^3YzE=73WCZk7`Ja^JJfke#GgDHnZA)QYL) z$JC35*!Pw~Hifp4SHsPd>2!#3IchVqY9vqiiP*KS*qYE}YOD%f*xRbO{wK`DKq_*j z0-3;Yv*4GYP30c5CpJp%CoHUr3HqaNU1w7`86)TL6TF706Ooj~1z5?!`PQ6Wi9!YT zn%3j|?};jLN6%goqU;Iuf=<8CV1@RMmk3^Z+Ptor)-T%Xh<&qnc@P(>-IkYX^0ym# z?mBuRjpWI3IbAZ(GWE0*lhs%sASA?u4U1hPWWOEfR)WBpcq=~)ZWAX&*Ac{zDs~&# z=QBWTkBuE*H+iVv$2Za5U%5@$m~lR22EG8+!vr^)q4hc_FH*m5gM3-6ti$(3-h9$S zL&yfC&-%92`LhcILu~bz1K(Cp^m?b@fw@857iO~jWl_lWiNu%PPmo^QG9Tp!Ghk>u zkD8`jZN8vcrOeXJmfm7>f}56*vVsK8ZnB!;fpx#fRwL6Fm~N?{r3jpk1k-+!c&oOw zBwMh|v^}0*OVfNrWMD$MNyHzta8;z!Ks39b9K9H`RA%YaR(*;Vc7Z!ZoNRTJ6pANo zA1^jhh?&+sz+JAuToYP9IlEoD?X)F)rYjx!b&o%4dUncsCjTDL#Y`&bI{F(gE_l8-G?gunM4o8+Gg)B(c5WQk%DgjqZAEMeQNUO zVh!+2XOo%&9)>72`sb$oA3$M`gwf*b$c7o9ifqI)UrY0y(k)lQlx2J}mackh@=p5p zPOI;Sw|NZ(eLrUIy5t;*d{X*TxfWqzI~=F1?!lpuH@Pw-W+d8?|b-L?h+JAY@}-Z!{NAz zrUI(gq-CFGNi!*VXAGAS6)>SGg;`|KXA!AI2ag!pmfg?op{t)#K%I@EJ~foQ)+-*H z>ygNs4wnwgg#U6I{j-km1dXYQuc(DN@n^bM*UmqaqqE^T(gnP6m^P&ed7l748=JICZ$`l-7OJ)bfcNt6?xguUJ}Q@058S!zs}KXqT_ zuk6*%Ki^EnYmY{?4=HHgB<(*!^vwt*bGYS-hSJOPWp1G4j09B8ZlP5Wndwl0J3&FJ z@`P`<%!y~G!;*yLoqKNwh-(bQL|8JVRC0h_z1J0}qK{b74B_`SE_AiUiHOuYTGV!% z4)W@8GalP9RygB!OHZ&{C6&akWqohyqze_;w~Q8n`6K#RD65XnsLnil;PHv49`q)< zGMpl+1cvZLDx+`m%GD&aozlD3TrqLeAd>%BF@hxH+V42IH|LIQxnd1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file diff --git a/tests/e2e/solc_parsing/test_data/expected/aliasing/alias-unit-NewContract.sol-0.8.19-compact.json b/tests/e2e/solc_parsing/test_data/expected/aliasing/alias-unit-NewContract.sol-0.8.19-compact.json new file mode 100644 index 0000000000..b0ce256111 --- /dev/null +++ b/tests/e2e/solc_parsing/test_data/expected/aliasing/alias-unit-NewContract.sol-0.8.19-compact.json @@ -0,0 +1,6 @@ +{ + "MyContract": {}, + "Test": { + "constructor()": "digraph{\n0[label=\"Node Type: ENTRY_POINT 0\n\"];\n0->1;\n1[label=\"Node Type: EXPRESSION 1\n\"];\n}\n" + } +} \ No newline at end of file From 294850f2f128853b73784caa18399db4c7a7b87e Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 21 Mar 2024 22:17:04 -0500 Subject: [PATCH 2/2] add missing file --- tests/e2e/solc_parsing/test_data/aliasing/MyContract.sol | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/e2e/solc_parsing/test_data/aliasing/MyContract.sol diff --git a/tests/e2e/solc_parsing/test_data/aliasing/MyContract.sol b/tests/e2e/solc_parsing/test_data/aliasing/MyContract.sol new file mode 100644 index 0000000000..ab7b85a102 --- /dev/null +++ b/tests/e2e/solc_parsing/test_data/aliasing/MyContract.sol @@ -0,0 +1 @@ +contract MyContract {} \ No newline at end of file