diff --git a/404.html b/404.html index bf876bb..6ef7859 100644 --- a/404.html +++ b/404.html @@ -3,11 +3,11 @@ -Page Not Found | CyScout - - +Page Not Found | CyScout + + -
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

\ No newline at end of file diff --git a/assets/js/0058b4c6.01669bb9.js b/assets/js/0058b4c6.01669bb9.js deleted file mode 100644 index 26ded99..0000000 --- a/assets/js/0058b4c6.01669bb9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[849],{6164:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"Classes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Access","href":"/docs/Classes/Access","docId":"Classes/Access","unlisted":false},{"type":"link","label":"BasicBlock","href":"/docs/Classes/BasicBlock","docId":"Classes/BasicBlock","unlisted":false},{"type":"link","label":"Block Statement","href":"/docs/Classes/Block","docId":"Classes/Block","unlisted":false},{"type":"link","label":"Call","href":"/docs/Classes/Call","docId":"Classes/Call","unlisted":false},{"type":"link","label":"Control Flow Graph","href":"/docs/Classes/ControlFlowGraph","docId":"Classes/ControlFlowGraph","unlisted":false},{"type":"link","label":"Enclosing","href":"/docs/Classes/Enclosing","docId":"Classes/Enclosing","unlisted":false},{"type":"link","label":"Function","href":"/docs/Classes/Function","docId":"Classes/Function","unlisted":false},{"type":"link","label":"Specifier","href":"/docs/Classes/Specifier","docId":"Classes/Specifier","unlisted":false},{"type":"link","label":"SubBasicBlock","href":"/docs/Classes/SubBasicBlock","docId":"Classes/SubBasicBlock","unlisted":false},{"type":"link","label":"Variable","href":"/docs/Classes/Variable","docId":"Classes/Variable","unlisted":false},{"type":"link","label":"Index","href":"/docs/Classes/classesIndex","docId":"Classes/classesIndex","unlisted":false}]},{"type":"category","label":"Detectors Index","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Divide before multiply","href":"/docs/Detectors/divide-before-multiply","docId":"Detectors/divide-before-multiply","unlisted":false},{"type":"link","label":"Incorrect exponentiation","href":"/docs/Detectors/incorrect-exp","docId":"Detectors/incorrect-exp","unlisted":false},{"type":"link","label":"incorrect-shift","href":"/docs/Detectors/incorrect-shift","docId":"Detectors/incorrect-shift","unlisted":false},{"type":"link","label":"is-unreachable","href":"/docs/Detectors/is-unreachable","docId":"Detectors/is-unreachable","unlisted":false},{"type":"link","label":"msg-value-in-for-loop","href":"/docs/Detectors/msg-value-in-for-loop","docId":"Detectors/msg-value-in-for-loop","unlisted":false},{"type":"link","label":"transfer-from","href":"/docs/Detectors/transfer-from","docId":"Detectors/transfer-from","unlisted":false},{"type":"link","label":"Unchecked Send","href":"/docs/Detectors/unchecked-send","docId":"Detectors/unchecked-send","unlisted":false},{"type":"link","label":"Unrpotected self destruct","href":"/docs/Detectors/unprotected-self-destruct","docId":"Detectors/unprotected-self-destruct","unlisted":false}],"href":"/docs/Detectors/"},{"type":"category","label":"CyScout","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"det01_doc","href":"/docs/README/det01_doc","docId":"README/det01_doc","unlisted":false},{"type":"link","label":"det02_doc","href":"/docs/README/det02_doc","docId":"README/det02_doc","unlisted":false},{"type":"link","label":"det03_doc","href":"/docs/README/det03_doc","docId":"README/det03_doc","unlisted":false},{"type":"link","label":"det04_doc","href":"/docs/README/det04_doc","docId":"README/det04_doc","unlisted":false}],"href":"/docs/README/"}]},"docs":{"Classes/Access":{"id":"Classes/Access","title":"Access","description":"Classes","sidebar":"tutorialSidebar"},"Classes/BasicBlock":{"id":"Classes/BasicBlock","title":"BasicBlock","description":"Provides a library for reasoning about control flow at the granularity of basic blocks. This is usually much more efficient than reasoning directly at the level of ControlFlowNodes.","sidebar":"tutorialSidebar"},"Classes/Block":{"id":"Classes/Block","title":"Block Statement","description":"Implements a class to model a solidity block statement","sidebar":"tutorialSidebar"},"Classes/Call":{"id":"Classes/Call","title":"Call","description":"Classes","sidebar":"tutorialSidebar"},"Classes/classesIndex":{"id":"Classes/classesIndex","title":"Index","description":"- Access","sidebar":"tutorialSidebar"},"Classes/ControlFlowGraph":{"id":"Classes/ControlFlowGraph","title":"Control Flow Graph","description":"In this module there is","sidebar":"tutorialSidebar"},"Classes/Enclosing":{"id":"Classes/Enclosing","title":"Enclosing","description":"Provides predicates for finding the smallest element that encloses an expression or statement.","sidebar":"tutorialSidebar"},"Classes/Function":{"id":"Classes/Function","title":"Function","description":"Methods","sidebar":"tutorialSidebar"},"Classes/Specifier":{"id":"Classes/Specifier","title":"Specifier","description":"Provides classes for modeling specifiers and attributes.","sidebar":"tutorialSidebar"},"Classes/SubBasicBlock":{"id":"Classes/SubBasicBlock","title":"SubBasicBlock","description":"Provides the SubBasicBlock class, used for partitioning basic blocks in smaller pieces.","sidebar":"tutorialSidebar"},"Classes/Variable":{"id":"Classes/Variable","title":"Variable","description":"Classes","sidebar":"tutorialSidebar"},"Detectors/divide-before-multiply":{"id":"Detectors/divide-before-multiply","title":"Divide before multiply","description":"Description","sidebar":"tutorialSidebar"},"Detectors/incorrect-exp":{"id":"Detectors/incorrect-exp","title":"Incorrect exponentiation","description":"Description","sidebar":"tutorialSidebar"},"Detectors/incorrect-shift":{"id":"Detectors/incorrect-shift","title":"incorrect-shift","description":"Incorrect shift in assembly","sidebar":"tutorialSidebar"},"Detectors/index":{"id":"Detectors/index","title":"Detectors Index","description":"- deadCode","sidebar":"tutorialSidebar"},"Detectors/is-unreachable":{"id":"Detectors/is-unreachable","title":"is-unreachable","description":"Is unreachable","sidebar":"tutorialSidebar"},"Detectors/msg-value-in-for-loop":{"id":"Detectors/msg-value-in-for-loop","title":"msg-value-in-for-loop","description":"msg.value in for loops","sidebar":"tutorialSidebar"},"Detectors/transfer-from":{"id":"Detectors/transfer-from","title":"transfer-from","description":"transfer-from uses arbitrary from","sidebar":"tutorialSidebar"},"Detectors/unchecked-send":{"id":"Detectors/unchecked-send","title":"Unchecked Send","description":"Description","sidebar":"tutorialSidebar"},"Detectors/unprotected-self-destruct":{"id":"Detectors/unprotected-self-destruct","title":"Unrpotected self destruct","description":"Description","sidebar":"tutorialSidebar"},"README/det01_doc":{"id":"README/det01_doc","title":"det01_doc","description":"transferFrom uses arbitrary from","sidebar":"tutorialSidebar"},"README/det02_doc":{"id":"README/det02_doc","title":"det02_doc","description":"\'FIX\' word in comments","sidebar":"tutorialSidebar"},"README/det03_doc":{"id":"README/det03_doc","title":"det03_doc","description":"Incorrect shift in assembly","sidebar":"tutorialSidebar"},"README/det04_doc":{"id":"README/det04_doc","title":"det04_doc","description":"Dead code","sidebar":"tutorialSidebar"},"README/readme":{"id":"README/readme","title":"CyScout","description":"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/0fedfb09.4191da60.js b/assets/js/0fedfb09.4191da60.js deleted file mode 100644 index 9671ec6..0000000 --- a/assets/js/0fedfb09.4191da60.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[871],{8572:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>a});var t=n(6070),r=n(1503);const s={},c="Function",l={id:"Classes/Function",title:"Function",description:"Methods",source:"@site/docs/Classes/Function.md",sourceDirName:"Classes",slug:"/Classes/Function",permalink:"/docs/Classes/Function",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Function.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Enclosing",permalink:"/docs/Classes/Enclosing"},next:{title:"Specifier",permalink:"/docs/Classes/Specifier"}},o={},a=[{value:"Methods",id:"methods",level:2},{value:"hasSpecifier(string name)",id:"hasspecifierstring-name",level:3},{value:"getASpecifier()",id:"getaspecifier",level:3},{value:"isVirtual()",id:"isvirtual",level:3},{value:"getAParameter()",id:"getaparameter",level:3},{value:"getNumberOfParameters()",id:"getnumberofparameters",level:3},{value:"getEffectiveNumberOfParameters()",id:"geteffectivenumberofparameters",level:3},{value:"getACallToThisFunction()",id:"getacalltothisfunction",level:3},{value:"getControlFlowScope()",id:"getcontrolflowscope",level:3},{value:"getEnclosingStmt()",id:"getenclosingstmt",level:3}];function d(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"function",children:"Function"})}),"\n",(0,t.jsx)(i.h2,{id:"methods",children:"Methods"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#hasspecifierstring-name",children:"hasSpecifier(string name)"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#getaspecifier",children:"getASpecifier()"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#isvirtual",children:"isVirtual()"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#getnumberofparameters",children:"getNumberOfParameters()"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#geteffectivenumberofparameters",children:"getEffectiveNumberOfParameters()"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#getacalltothisfunction",children:"getACallToThisFunction()"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#getcontrolflowscope",children:"getControlFlowScope()"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"#getenclosingstmt",children:"getEnclosingStmt()"})}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"hasspecifierstring-name",children:"hasSpecifier(string name)"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"predicate hasSpecifier(string name) { this.getASpecifier().hasName(name) }\n"})}),"\n",(0,t.jsx)(i.p,{children:"Holds if this declaration has a specifier with the given name."}),"\n",(0,t.jsx)(i.h3,{id:"getaspecifier",children:"getASpecifier()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"Specifier getASpecifier() {\n exists(Specifier s | this.getAFieldOrChild() instanceof Specifier and result = s)\n}\n"})}),"\n",(0,t.jsx)(i.p,{children:"Gets a specifier of this function."}),"\n",(0,t.jsx)(i.h3,{id:"isvirtual",children:"isVirtual()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:'predicate isVirtual() { this.hasSpecifier("virtual") }\n'})}),"\n",(0,t.jsx)(i.p,{children:"Holds if this function is virtual."}),"\n",(0,t.jsxs)(i.p,{children:["Unlike ",(0,t.jsx)(i.code,{children:"isDeclaredVirtual()"}),", ",(0,t.jsx)(i.code,{children:"isVirtual()"})," holds even if the function is not explicitly declared with the ",(0,t.jsx)(i.code,{children:"virtual"})," specifier."]}),"\n",(0,t.jsx)(i.h3,{id:"getaparameter",children:"getAParameter()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"Solidity::Parameter getAParameter() { result = any(this.getChild(_)) }\n"})}),"\n",(0,t.jsxs)(i.p,{children:["Gets a parameter of this function. There is no result for the implicit ",(0,t.jsx)(i.code,{children:"this"})," parameter, and there is no ",(0,t.jsx)(i.code,{children:"..."})," varargs pseudo-parameter."]}),"\n",(0,t.jsx)(i.h3,{id:"getnumberofparameters",children:"getNumberOfParameters()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"int getNumberOfParameters() { result = count(this.getAParameter()) }\n"})}),"\n",(0,t.jsxs)(i.p,{children:["Gets the number of parameters of this function, ",(0,t.jsx)(i.em,{children:"not"})," including any implicit ",(0,t.jsx)(i.code,{children:"this"})," parameter or any ",(0,t.jsx)(i.code,{children:"..."})," varargs pseudo-parameter."]}),"\n",(0,t.jsx)(i.h3,{id:"geteffectivenumberofparameters",children:"getEffectiveNumberOfParameters()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"int getEffectiveNumberOfParameters() {\n // This method is overridden in `MemberFunction`, where the result is\n // adjusted to account for the implicit `this` parameter.\n result = this.getNumberOfParameters()\n}\n"})}),"\n",(0,t.jsxs)(i.p,{children:["Gets the number of parameters of this function, ",(0,t.jsx)(i.em,{children:"including"})," any implicit ",(0,t.jsx)(i.code,{children:"this"})," parameter but ",(0,t.jsx)(i.em,{children:"not"})," including any ",(0,t.jsx)(i.code,{children:"..."})," varargs pseudo-parameter."]}),"\n",(0,t.jsx)(i.h3,{id:"getacalltothisfunction",children:"getACallToThisFunction()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"FunctionCall getACallToThisFunction() { result.getTarget() = this }\n\n"})}),"\n",(0,t.jsx)(i.p,{children:"Gets a call to this function."}),"\n",(0,t.jsx)(i.h3,{id:"getcontrolflowscope",children:"getControlFlowScope()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"override Function getControlFlowScope() { result = this }\n"})}),"\n",(0,t.jsxs)(i.p,{children:["Implements ",(0,t.jsx)(i.code,{children:"ControlFlowNode.getControlFlowScope"}),". The ",(0,t.jsx)(i.code,{children:"Function"})," is used to represent the exit node of the control flow graph, so it is its own scope."]}),"\n",(0,t.jsx)(i.h3,{id:"getenclosingstmt",children:"getEnclosingStmt()"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"override Stmt getEnclosingStmt() { none() }\n"})}),"\n",(0,t.jsxs)(i.p,{children:["Implements ",(0,t.jsx)(i.code,{children:"ControlFlowNode.getEnclosingStmt"}),". The ",(0,t.jsx)(i.code,{children:"Function"})," is used to represent the exit node of the control flow graph, so it has no enclosing statement."]})]})}function h(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1503:(e,i,n)=>{n.d(i,{R:()=>c,x:()=>l});var t=n(758);const r={},s=t.createContext(r);function c(e){const i=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0fedfb09.4a4e9a81.js b/assets/js/0fedfb09.4a4e9a81.js new file mode 100644 index 0000000..28a3454 --- /dev/null +++ b/assets/js/0fedfb09.4a4e9a81.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[871],{8572:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>a});var n=i(6070),r=i(1503);const s={},c="Function",l={id:"Classes/Function",title:"Function",description:"Methods",source:"@site/docs/Classes/Function.md",sourceDirName:"Classes",slug:"/Classes/Function",permalink:"/CyScout/docs/Classes/Function",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Function.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Enclosing",permalink:"/CyScout/docs/Classes/Enclosing"},next:{title:"Specifier",permalink:"/CyScout/docs/Classes/Specifier"}},o={},a=[{value:"Methods",id:"methods",level:2},{value:"hasSpecifier(string name)",id:"hasspecifierstring-name",level:3},{value:"getASpecifier()",id:"getaspecifier",level:3},{value:"isVirtual()",id:"isvirtual",level:3},{value:"getAParameter()",id:"getaparameter",level:3},{value:"getNumberOfParameters()",id:"getnumberofparameters",level:3},{value:"getEffectiveNumberOfParameters()",id:"geteffectivenumberofparameters",level:3},{value:"getACallToThisFunction()",id:"getacalltothisfunction",level:3},{value:"getControlFlowScope()",id:"getcontrolflowscope",level:3},{value:"getEnclosingStmt()",id:"getenclosingstmt",level:3}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"function",children:"Function"})}),"\n",(0,n.jsx)(t.h2,{id:"methods",children:"Methods"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#hasspecifierstring-name",children:"hasSpecifier(string name)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#getaspecifier",children:"getASpecifier()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#isvirtual",children:"isVirtual()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#getnumberofparameters",children:"getNumberOfParameters()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#geteffectivenumberofparameters",children:"getEffectiveNumberOfParameters()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#getacalltothisfunction",children:"getACallToThisFunction()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#getcontrolflowscope",children:"getControlFlowScope()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"#getenclosingstmt",children:"getEnclosingStmt()"})}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"hasspecifierstring-name",children:"hasSpecifier(string name)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"predicate hasSpecifier(string name) { this.getASpecifier().hasName(name) }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Holds if this declaration has a specifier with the given name."}),"\n",(0,n.jsx)(t.h3,{id:"getaspecifier",children:"getASpecifier()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Specifier getASpecifier() {\n exists(Specifier s | this.getAFieldOrChild() instanceof Specifier and result = s)\n}\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets a specifier of this function."}),"\n",(0,n.jsx)(t.h3,{id:"isvirtual",children:"isVirtual()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'predicate isVirtual() { this.hasSpecifier("virtual") }\n'})}),"\n",(0,n.jsx)(t.p,{children:"Holds if this function is virtual."}),"\n",(0,n.jsxs)(t.p,{children:["Unlike ",(0,n.jsx)(t.code,{children:"isDeclaredVirtual()"}),", ",(0,n.jsx)(t.code,{children:"isVirtual()"})," holds even if the function is not explicitly declared with the ",(0,n.jsx)(t.code,{children:"virtual"})," specifier."]}),"\n",(0,n.jsx)(t.h3,{id:"getaparameter",children:"getAParameter()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Solidity::Parameter getAParameter() { result = any(this.getChild(_)) }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Gets a parameter of this function. There is no result for the implicit ",(0,n.jsx)(t.code,{children:"this"})," parameter, and there is no ",(0,n.jsx)(t.code,{children:"..."})," varargs pseudo-parameter."]}),"\n",(0,n.jsx)(t.h3,{id:"getnumberofparameters",children:"getNumberOfParameters()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"int getNumberOfParameters() { result = count(this.getAParameter()) }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Gets the number of parameters of this function, ",(0,n.jsx)(t.em,{children:"not"})," including any implicit ",(0,n.jsx)(t.code,{children:"this"})," parameter or any ",(0,n.jsx)(t.code,{children:"..."})," varargs pseudo-parameter."]}),"\n",(0,n.jsx)(t.h3,{id:"geteffectivenumberofparameters",children:"getEffectiveNumberOfParameters()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"int getEffectiveNumberOfParameters() {\n // This method is overridden in `MemberFunction`, where the result is\n // adjusted to account for the implicit `this` parameter.\n result = this.getNumberOfParameters()\n}\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Gets the number of parameters of this function, ",(0,n.jsx)(t.em,{children:"including"})," any implicit ",(0,n.jsx)(t.code,{children:"this"})," parameter but ",(0,n.jsx)(t.em,{children:"not"})," including any ",(0,n.jsx)(t.code,{children:"..."})," varargs pseudo-parameter."]}),"\n",(0,n.jsx)(t.h3,{id:"getacalltothisfunction",children:"getACallToThisFunction()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"FunctionCall getACallToThisFunction() { result.getTarget() = this }\n\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets a call to this function."}),"\n",(0,n.jsx)(t.h3,{id:"getcontrolflowscope",children:"getControlFlowScope()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"override Function getControlFlowScope() { result = this }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Implements ",(0,n.jsx)(t.code,{children:"ControlFlowNode.getControlFlowScope"}),". The ",(0,n.jsx)(t.code,{children:"Function"})," is used to represent the exit node of the control flow graph, so it is its own scope."]}),"\n",(0,n.jsx)(t.h3,{id:"getenclosingstmt",children:"getEnclosingStmt()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"override Stmt getEnclosingStmt() { none() }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Implements ",(0,n.jsx)(t.code,{children:"ControlFlowNode.getEnclosingStmt"}),". The ",(0,n.jsx)(t.code,{children:"Function"})," is used to represent the exit node of the control flow graph, so it has no enclosing statement."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1503:(e,t,i)=>{i.d(t,{R:()=>c,x:()=>l});var n=i(758);const r={},s=n.createContext(r);function c(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1e4ea422.bf1e03cf.js b/assets/js/1e4ea422.bf1e03cf.js new file mode 100644 index 0000000..368116f --- /dev/null +++ b/assets/js/1e4ea422.bf1e03cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[575],{7745:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=n(6070),s=n(1503);const o={},c="Detectors Index",i={id:"Detectors/index",title:"Detectors Index",description:"- deadCode",source:"@site/docs/Detectors/index.md",sourceDirName:"Detectors",slug:"/Detectors/",permalink:"/CyScout/docs/Detectors/",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/index.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Index",permalink:"/CyScout/docs/Classes/classesIndex"},next:{title:"Divide before multiply",permalink:"/CyScout/docs/Detectors/divide-before-multiply"}},d={},l=[];function a(e){const t={h1:"h1",header:"header",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"detectors-index",children:"Detectors Index"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"deadCode"}),"\n",(0,r.jsx)(t.li,{children:"fixWordInComments"}),"\n",(0,r.jsx)(t.li,{children:"incorrectShift"}),"\n",(0,r.jsx)(t.li,{children:"msgValueInForLoop"}),"\n",(0,r.jsx)(t.li,{children:"transferFrom"}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},1503:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var r=n(758);const s={},o=r.createContext(s);function c(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1e4ea422.e56a88db.js b/assets/js/1e4ea422.e56a88db.js deleted file mode 100644 index ab51bb6..0000000 --- a/assets/js/1e4ea422.e56a88db.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[575],{7745:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=n(6070),s=n(1503);const o={},c="Detectors Index",i={id:"Detectors/index",title:"Detectors Index",description:"- deadCode",source:"@site/docs/Detectors/index.md",sourceDirName:"Detectors",slug:"/Detectors/",permalink:"/docs/Detectors/",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/index.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Index",permalink:"/docs/Classes/classesIndex"},next:{title:"Divide before multiply",permalink:"/docs/Detectors/divide-before-multiply"}},d={},l=[];function a(e){const t={h1:"h1",header:"header",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"detectors-index",children:"Detectors Index"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"deadCode"}),"\n",(0,r.jsx)(t.li,{children:"fixWordInComments"}),"\n",(0,r.jsx)(t.li,{children:"incorrectShift"}),"\n",(0,r.jsx)(t.li,{children:"msgValueInForLoop"}),"\n",(0,r.jsx)(t.li,{children:"transferFrom"}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},1503:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var r=n(758);const s={},o=r.createContext(s);function c(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/393be207.31664e14.js b/assets/js/393be207.31664e14.js deleted file mode 100644 index 593d911..0000000 --- a/assets/js/393be207.31664e14.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[134],{4561:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>s,default:()=>i,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var a=t(6070),o=t(1503);const r={title:"Markdown page example"},s="Markdown page example",c={type:"mdx",permalink:"/markdown-page",source:"@site/src/pages/markdown-page.md",title:"Markdown page example",description:"You don't need React to write simple standalone pages.",frontMatter:{title:"Markdown page example"},unlisted:!1},p={},d=[];function l(e){const n={h1:"h1",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"markdown-page-example",children:"Markdown page example"})}),"\n",(0,a.jsx)(n.p,{children:"You don't need React to write simple standalone pages."})]})}function i(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var a=t(758);const o={},r=a.createContext(o);function s(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/393be207.64cc58d0.js b/assets/js/393be207.64cc58d0.js new file mode 100644 index 0000000..6d0652b --- /dev/null +++ b/assets/js/393be207.64cc58d0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[134],{4561:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>s,default:()=>i,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var o=t(6070),a=t(1503);const r={title:"Markdown page example"},s="Markdown page example",c={type:"mdx",permalink:"/CyScout/markdown-page",source:"@site/src/pages/markdown-page.md",title:"Markdown page example",description:"You don't need React to write simple standalone pages.",frontMatter:{title:"Markdown page example"},unlisted:!1},p={},d=[];function l(e){const n={h1:"h1",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"markdown-page-example",children:"Markdown page example"})}),"\n",(0,o.jsx)(n.p,{children:"You don't need React to write simple standalone pages."})]})}function i(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var o=t(758);const a={},r=o.createContext(a);function s(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4b0e7aa3.a3afdd6a.js b/assets/js/4b0e7aa3.a3afdd6a.js deleted file mode 100644 index b840e40..0000000 --- a/assets/js/4b0e7aa3.a3afdd6a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[568],{484:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>n,metadata:()=>d,toc:()=>c});var s=i(6070),o=i(1503);const n={},r="CyScout",d={id:"README/readme",title:"CyScout",description:"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity",source:"@site/docs/README/readme.md",sourceDirName:"README",slug:"/README/",permalink:"/docs/README/",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/readme.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Unrpotected self destruct",permalink:"/docs/Detectors/unprotected-self-destruct"},next:{title:"det01_doc",permalink:"/docs/README/det01_doc"}},l={},c=[{value:"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity",id:"run-queries-and-detect-vulnerabilities-in-your-smart-contracts-using-codeql-solidity",level:2},{value:"\ud83d\udd0d Overview",id:"-overview",level:2},{value:"\ud83d\ude80 Project Status",id:"-project-status",level:2},{value:"\ud83c\udfc1 Getting Started",id:"-getting-started",level:2},{value:"1\ufe0f\u20e3 Install CodeQL CLI",id:"1\ufe0f\u20e3-install-codeql-cli",level:3},{value:"Clone CodeQL repository",id:"clone-codeql-repository",level:3},{value:"2\ufe0f\u20e3 Setting up Solidity Extractor",id:"2\ufe0f\u20e3-setting-up-solidity-extractor",level:3},{value:"3\ufe0f\u20e3 Extract Solidity Code",id:"3\ufe0f\u20e3-extract-solidity-code",level:3},{value:"4\ufe0f\u20e3 Run Sample Detectors",id:"4\ufe0f\u20e3-run-sample-detectors",level:3},{value:"Detectors",id:"detectors",level:2},{value:"Further Documentation",id:"further-documentation",level:3},{value:"\ud83e\udd1d Contributing",id:"-contributing",level:2},{value:"License",id:"license",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"cyscout",children:"CyScout"})}),"\n",(0,s.jsx)(t.h2,{id:"run-queries-and-detect-vulnerabilities-in-your-smart-contracts-using-codeql-solidity",children:"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"alt text",src:i(7226).A+"",width:"378",height:"177"})}),"\n",(0,s.jsx)(t.p,{children:"This repository contains CoinFabrik's ongoing research and development to extend CodeQL support to the Solidity smart contract language. By leveraging the foundational work done by the CodeQL team for Ruby, we have adapted and expanded their approach to create a powerful toolset for analyzing Solidity code."}),"\n",(0,s.jsx)(t.h2,{id:"-overview",children:"\ud83d\udd0d Overview"}),"\n",(0,s.jsxs)(t.p,{children:["Our goal is to provide a comprehensive set of tools for querying and detecting vulnerabilities in Solidity smart contracts. We build upon the work of ",(0,s.jsx)(t.a,{href:"https://github.com/JoranHonig/tree-sitter-solidity",children:"Joran Honig's Solidity Tree-sitter grammar"})," and the CodeQL team's ",(0,s.jsx)(t.a,{href:"https://github.blog/security/web-application-security/code-scanning-and-ruby-turning-source-code-into-a-queryable-database/",children:"Ruby implementation"}),". The project includes an extractor, database schema generation, and abstractions such as a cleaner Abstract Syntax Tree (AST), Control Flow Graph (CFG), and Dataflow analysis. These elements enable complex vulnerability detection and querying, similar to the C++ libraries in CodeQL."]}),"\n",(0,s.jsx)(t.h2,{id:"-project-status",children:"\ud83d\ude80 Project Status"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Extractor and Database Schema"}),": Usable and functional for Solidity codebases."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Current Work"}),": We are actively developing a cleaner AST, CFG, and Dataflow support to enhance the detection of vulnerabilities."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Proof of Concept (PoC)"}),": Three simple detector examples are provided to demonstrate basic usage and potential."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"-getting-started",children:"\ud83c\udfc1 Getting Started"}),"\n",(0,s.jsx)(t.p,{children:"To get started with analyzing Solidity smart contracts using CodeQL, follow these steps:"}),"\n",(0,s.jsx)(t.h3,{id:"1\ufe0f\u20e3-install-codeql-cli",children:"1\ufe0f\u20e3 Install CodeQL CLI"}),"\n",(0,s.jsxs)(t.p,{children:["First, download and install the CodeQL CLI by following the instructions provided in the ",(0,s.jsx)(t.a,{href:"https://github.com/github/codeql-cli-binaries",children:"official CodeQL CLI repository"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"clone-codeql-repository",children:"Clone CodeQL repository"}),"\n",(0,s.jsxs)(t.p,{children:["Clone this repository from ",(0,s.jsx)(t.a,{href:"https://github.com/github/codeql",children:"CodeQl"})]}),"\n",(0,s.jsx)(t.h3,{id:"2\ufe0f\u20e3-setting-up-solidity-extractor",children:"2\ufe0f\u20e3 Setting up Solidity Extractor"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Go to ",(0,s.jsx)(t.code,{children:"codeql-research/solidity/extractor-pack/tools"})," and give all ",(0,s.jsx)(t.code,{children:".sh"})," files execute permissions. This is:"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"chmod +x *.sh\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Copy the ",(0,s.jsx)(t.code,{children:"solidity"})," and ",(0,s.jsx)(t.code,{children:"solidity-test"})," folders of this repository (",(0,s.jsx)(t.code,{children:"codeql-research"}),") inside ",(0,s.jsx)(t.code,{children:"CodeQL CLI repository"})," and ",(0,s.jsx)(t.code,{children:"CodeQL"}),". Both at root level."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Inside ",(0,s.jsx)(t.code,{children:"CodeQL"})," repository, in this path ",(0,s.jsx)(t.code,{children:"codeql/solidity"})," run:"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"bash scripts/create-extractor-pack.sh\n"})}),"\n",(0,s.jsx)(t.p,{children:"--\x3e"}),"\n",(0,s.jsx)(t.h3,{id:"3\ufe0f\u20e3-extract-solidity-code",children:"3\ufe0f\u20e3 Extract Solidity Code"}),"\n",(0,s.jsx)(t.p,{children:"To create a CodeQL database from a Solidity codebase, run the following command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"codeql database create /path-to-database/ -l solidity -s /path-to-solidity-codebase/ --search-path /path-to-[solidity/extractor-pack]/\n"})}),"\n",(0,s.jsx)(t.p,{children:"If all went smoothly, you should see something of the kind:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"\ncodeql database create /home/user/codeql/solidity-test/test-db-bitshift-examples -l solidity -s /home/user/codeql/solidity-test/bitshift-order-test --search-path ../solidity/extractor-pack --overwrite\nInitializing database at /home/user/codeql/solidity-test/test-db-bitshift-examples.\nRunning build command: []\nRunning command in /home/user/codeql/solidity-test/bitshift-order-test: [/home/user/codeql/solidity/extractor-pack/tools/autobuild.sh]\n[2024-09-03 12:55:56] [build-stderr] Scanning for files in /home/user/codeql/solidity-test/bitshift-order-test...\n[2024-09-03 12:55:56] [build-stderr] /home/user/codeql/solidity-test/test-db-bitshift-examples: Indexing files in in /home/user/codeql/solidity-test/bitshift-order-test...\n[2024-09-03 12:55:56] [build-stderr] Running command in /home/user/codeql/solidity-test/bitshift-order-test: [/home/user/codeql/solidity/extractor-pack/tools/index-files.sh, /home/user/codeql/solidity-test/test-db-bitshift-examples/working/files-to-index13975833793457248559.list]\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO Extraction started\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO Using 7 threads\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO extracting: /home/user/codeql/solidity-test/bitshift-order-test/remediated.sol\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO extracting: /home/user/codeql/solidity-test/bitshift-order-test/vulnerable.sol\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO Extraction complete\nFinalizing database at /home/user/codeql/solidity-test/test-db-bitshift-examples.\nRunning TRAP import for CodeQL database at /home/user/codeql/solidity-test/test-db-bitshift-examples...\nImporting TRAP files\nMerging relations\nFinished writing database (relations: 4.86 KiB; string pool: 2.05 MiB).\nTRAP import complete (983ms).\nFinished zipping source archive (643.00 B).\nSuccessfully created database at /home/user/codeql/solidity-test/test-db-bitshift-examples.\n\n"})}),"\n",(0,s.jsx)(t.h3,{id:"4\ufe0f\u20e3-run-sample-detectors",children:"4\ufe0f\u20e3 Run Sample Detectors"}),"\n",(0,s.jsx)(t.p,{children:"Once the database is created, you can run sample detectors written in the QL language:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"codeql query run /path-to-detector/ -d /path-to-created-database/\n"})}),"\n",(0,s.jsx)(t.p,{children:"For instance:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"[1/1] Found in cache: /home/user/codeql/solidity/ql/lib/detector3.ql.\ndetector3.ql: Evaluation completed (191ms).\n| col0 | col1 |\n+-----------------+------------------------------------------------------------------------------+\n| YulFunctionCall | /home/user/codeql/solidity-test/bitshift-order-test/vulnerable.sol@4:18:4:26 |\nShutting down query evaluator.\n"})}),"\n",(0,s.jsx)(t.h2,{id:"detectors",children:"Detectors"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Num"}),(0,s.jsx)(t.th,{children:"Detector"}),(0,s.jsx)(t.th,{children:"What it Detects"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"1"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector1"})}),(0,s.jsx)(t.td,{children:(0,s.jsxs)(t.a,{href:"/docs/README/det01_doc",children:["transferFrom uses arbitrary ",(0,s.jsx)(t.code,{children:"from"})]})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"2"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector2"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/docs/README/det02_doc",children:"usage of the word 'FIX' in comments"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"3"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector3"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/docs/README/det03_doc",children:"incorrect order of arguments in bit shift operations"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"4"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector3"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/docs/README/det03_doc",children:"Dead code: unreachable basic blocks"})})]})]})]}),"\n",(0,s.jsx)(t.h3,{id:"further-documentation",children:"Further Documentation"}),"\n",(0,s.jsxs)(t.p,{children:["For more detailed instructions on using CodeQL, refer to the ",(0,s.jsx)(t.a,{href:"https://codeql.github.com/docs/",children:"official CodeQL documentation"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"-contributing",children:"\ud83e\udd1d Contributing"}),"\n",(0,s.jsx)(t.p,{children:"We welcome contributions to enhance and expand the support for Solidity in CodeQL. Feel free to submit issues, feature requests, or pull requests."}),"\n",(0,s.jsx)(t.h2,{id:"license",children:"License"}),"\n",(0,s.jsx)(t.p,{children:"The code in this repository is licensed under the MIT License by CoinFabrik."}),"\n",(0,s.jsxs)(t.p,{children:["For further information on CodeQL and CodeQL CLI licensing, please refer to the official ",(0,s.jsx)(t.a,{href:"https://github.com/github/codeql-cli-binaries",children:"repo"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},7226:(e,t,i)=>{i.d(t,{A:()=>s});const s=i.p+"assets/images/output-1649b3fc1ffdce14d0b6295e84a7b9aa.gif"},1503:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>d});var s=i(758);const o={},n=s.createContext(o);function r(e){const t=s.useContext(n);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4b0e7aa3.ff14f647.js b/assets/js/4b0e7aa3.ff14f647.js new file mode 100644 index 0000000..6d7db60 --- /dev/null +++ b/assets/js/4b0e7aa3.ff14f647.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[568],{484:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>n,metadata:()=>d,toc:()=>c});var s=i(6070),o=i(1503);const n={},r="CyScout",d={id:"README/readme",title:"CyScout",description:"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity",source:"@site/docs/README/readme.md",sourceDirName:"README",slug:"/README/",permalink:"/CyScout/docs/README/",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/readme.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Unrpotected self destruct",permalink:"/CyScout/docs/Detectors/unprotected-self-destruct"},next:{title:"det01_doc",permalink:"/CyScout/docs/README/det01_doc"}},l={},c=[{value:"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity",id:"run-queries-and-detect-vulnerabilities-in-your-smart-contracts-using-codeql-solidity",level:2},{value:"\ud83d\udd0d Overview",id:"-overview",level:2},{value:"\ud83d\ude80 Project Status",id:"-project-status",level:2},{value:"\ud83c\udfc1 Getting Started",id:"-getting-started",level:2},{value:"1\ufe0f\u20e3 Install CodeQL CLI",id:"1\ufe0f\u20e3-install-codeql-cli",level:3},{value:"Clone CodeQL repository",id:"clone-codeql-repository",level:3},{value:"2\ufe0f\u20e3 Setting up Solidity Extractor",id:"2\ufe0f\u20e3-setting-up-solidity-extractor",level:3},{value:"3\ufe0f\u20e3 Extract Solidity Code",id:"3\ufe0f\u20e3-extract-solidity-code",level:3},{value:"4\ufe0f\u20e3 Run Sample Detectors",id:"4\ufe0f\u20e3-run-sample-detectors",level:3},{value:"Detectors",id:"detectors",level:2},{value:"Further Documentation",id:"further-documentation",level:3},{value:"\ud83e\udd1d Contributing",id:"-contributing",level:2},{value:"License",id:"license",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"cyscout",children:"CyScout"})}),"\n",(0,s.jsx)(t.h2,{id:"run-queries-and-detect-vulnerabilities-in-your-smart-contracts-using-codeql-solidity",children:"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"alt text",src:i(7226).A+"",width:"378",height:"177"})}),"\n",(0,s.jsx)(t.p,{children:"This repository contains CoinFabrik's ongoing research and development to extend CodeQL support to the Solidity smart contract language. By leveraging the foundational work done by the CodeQL team for Ruby, we have adapted and expanded their approach to create a powerful toolset for analyzing Solidity code."}),"\n",(0,s.jsx)(t.h2,{id:"-overview",children:"\ud83d\udd0d Overview"}),"\n",(0,s.jsxs)(t.p,{children:["Our goal is to provide a comprehensive set of tools for querying and detecting vulnerabilities in Solidity smart contracts. We build upon the work of ",(0,s.jsx)(t.a,{href:"https://github.com/JoranHonig/tree-sitter-solidity",children:"Joran Honig's Solidity Tree-sitter grammar"})," and the CodeQL team's ",(0,s.jsx)(t.a,{href:"https://github.blog/security/web-application-security/code-scanning-and-ruby-turning-source-code-into-a-queryable-database/",children:"Ruby implementation"}),". The project includes an extractor, database schema generation, and abstractions such as a cleaner Abstract Syntax Tree (AST), Control Flow Graph (CFG), and Dataflow analysis. These elements enable complex vulnerability detection and querying, similar to the C++ libraries in CodeQL."]}),"\n",(0,s.jsx)(t.h2,{id:"-project-status",children:"\ud83d\ude80 Project Status"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Extractor and Database Schema"}),": Usable and functional for Solidity codebases."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Current Work"}),": We are actively developing a cleaner AST, CFG, and Dataflow support to enhance the detection of vulnerabilities."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Proof of Concept (PoC)"}),": Three simple detector examples are provided to demonstrate basic usage and potential."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"-getting-started",children:"\ud83c\udfc1 Getting Started"}),"\n",(0,s.jsx)(t.p,{children:"To get started with analyzing Solidity smart contracts using CodeQL, follow these steps:"}),"\n",(0,s.jsx)(t.h3,{id:"1\ufe0f\u20e3-install-codeql-cli",children:"1\ufe0f\u20e3 Install CodeQL CLI"}),"\n",(0,s.jsxs)(t.p,{children:["First, download and install the CodeQL CLI by following the instructions provided in the ",(0,s.jsx)(t.a,{href:"https://github.com/github/codeql-cli-binaries",children:"official CodeQL CLI repository"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"clone-codeql-repository",children:"Clone CodeQL repository"}),"\n",(0,s.jsxs)(t.p,{children:["Clone this repository from ",(0,s.jsx)(t.a,{href:"https://github.com/github/codeql",children:"CodeQl"})]}),"\n",(0,s.jsx)(t.h3,{id:"2\ufe0f\u20e3-setting-up-solidity-extractor",children:"2\ufe0f\u20e3 Setting up Solidity Extractor"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Go to ",(0,s.jsx)(t.code,{children:"codeql-research/solidity/extractor-pack/tools"})," and give all ",(0,s.jsx)(t.code,{children:".sh"})," files execute permissions. This is:"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"chmod +x *.sh\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Copy the ",(0,s.jsx)(t.code,{children:"solidity"})," and ",(0,s.jsx)(t.code,{children:"solidity-test"})," folders of this repository (",(0,s.jsx)(t.code,{children:"codeql-research"}),") inside ",(0,s.jsx)(t.code,{children:"CodeQL CLI repository"})," and ",(0,s.jsx)(t.code,{children:"CodeQL"}),". Both at root level."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Inside ",(0,s.jsx)(t.code,{children:"CodeQL"})," repository, in this path ",(0,s.jsx)(t.code,{children:"codeql/solidity"})," run:"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"bash scripts/create-extractor-pack.sh\n"})}),"\n",(0,s.jsx)(t.p,{children:"--\x3e"}),"\n",(0,s.jsx)(t.h3,{id:"3\ufe0f\u20e3-extract-solidity-code",children:"3\ufe0f\u20e3 Extract Solidity Code"}),"\n",(0,s.jsx)(t.p,{children:"To create a CodeQL database from a Solidity codebase, run the following command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"codeql database create /path-to-database/ -l solidity -s /path-to-solidity-codebase/ --search-path /path-to-[solidity/extractor-pack]/\n"})}),"\n",(0,s.jsx)(t.p,{children:"If all went smoothly, you should see something of the kind:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"\ncodeql database create /home/user/codeql/solidity-test/test-db-bitshift-examples -l solidity -s /home/user/codeql/solidity-test/bitshift-order-test --search-path ../solidity/extractor-pack --overwrite\nInitializing database at /home/user/codeql/solidity-test/test-db-bitshift-examples.\nRunning build command: []\nRunning command in /home/user/codeql/solidity-test/bitshift-order-test: [/home/user/codeql/solidity/extractor-pack/tools/autobuild.sh]\n[2024-09-03 12:55:56] [build-stderr] Scanning for files in /home/user/codeql/solidity-test/bitshift-order-test...\n[2024-09-03 12:55:56] [build-stderr] /home/user/codeql/solidity-test/test-db-bitshift-examples: Indexing files in in /home/user/codeql/solidity-test/bitshift-order-test...\n[2024-09-03 12:55:56] [build-stderr] Running command in /home/user/codeql/solidity-test/bitshift-order-test: [/home/user/codeql/solidity/extractor-pack/tools/index-files.sh, /home/user/codeql/solidity-test/test-db-bitshift-examples/working/files-to-index13975833793457248559.list]\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO Extraction started\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO Using 7 threads\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO extracting: /home/user/codeql/solidity-test/bitshift-order-test/remediated.sol\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO extracting: /home/user/codeql/solidity-test/bitshift-order-test/vulnerable.sol\n[2024-09-03 12:55:56] [build-stdout] [2024-09-03 12:55:56] [build-stdout] INFO Extraction complete\nFinalizing database at /home/user/codeql/solidity-test/test-db-bitshift-examples.\nRunning TRAP import for CodeQL database at /home/user/codeql/solidity-test/test-db-bitshift-examples...\nImporting TRAP files\nMerging relations\nFinished writing database (relations: 4.86 KiB; string pool: 2.05 MiB).\nTRAP import complete (983ms).\nFinished zipping source archive (643.00 B).\nSuccessfully created database at /home/user/codeql/solidity-test/test-db-bitshift-examples.\n\n"})}),"\n",(0,s.jsx)(t.h3,{id:"4\ufe0f\u20e3-run-sample-detectors",children:"4\ufe0f\u20e3 Run Sample Detectors"}),"\n",(0,s.jsx)(t.p,{children:"Once the database is created, you can run sample detectors written in the QL language:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"codeql query run /path-to-detector/ -d /path-to-created-database/\n"})}),"\n",(0,s.jsx)(t.p,{children:"For instance:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-shell",children:"[1/1] Found in cache: /home/user/codeql/solidity/ql/lib/detector3.ql.\ndetector3.ql: Evaluation completed (191ms).\n| col0 | col1 |\n+-----------------+------------------------------------------------------------------------------+\n| YulFunctionCall | /home/user/codeql/solidity-test/bitshift-order-test/vulnerable.sol@4:18:4:26 |\nShutting down query evaluator.\n"})}),"\n",(0,s.jsx)(t.h2,{id:"detectors",children:"Detectors"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Num"}),(0,s.jsx)(t.th,{children:"Detector"}),(0,s.jsx)(t.th,{children:"What it Detects"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"1"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector1"})}),(0,s.jsx)(t.td,{children:(0,s.jsxs)(t.a,{href:"/CyScout/docs/README/det01_doc",children:["transferFrom uses arbitrary ",(0,s.jsx)(t.code,{children:"from"})]})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"2"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector2"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/CyScout/docs/README/det02_doc",children:"usage of the word 'FIX' in comments"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"3"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector3"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/CyScout/docs/README/det03_doc",children:"incorrect order of arguments in bit shift operations"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"4"}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"detector3"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/CyScout/docs/README/det03_doc",children:"Dead code: unreachable basic blocks"})})]})]})]}),"\n",(0,s.jsx)(t.h3,{id:"further-documentation",children:"Further Documentation"}),"\n",(0,s.jsxs)(t.p,{children:["For more detailed instructions on using CodeQL, refer to the ",(0,s.jsx)(t.a,{href:"https://codeql.github.com/docs/",children:"official CodeQL documentation"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"-contributing",children:"\ud83e\udd1d Contributing"}),"\n",(0,s.jsx)(t.p,{children:"We welcome contributions to enhance and expand the support for Solidity in CodeQL. Feel free to submit issues, feature requests, or pull requests."}),"\n",(0,s.jsx)(t.h2,{id:"license",children:"License"}),"\n",(0,s.jsx)(t.p,{children:"The code in this repository is licensed under the MIT License by CoinFabrik."}),"\n",(0,s.jsxs)(t.p,{children:["For further information on CodeQL and CodeQL CLI licensing, please refer to the official ",(0,s.jsx)(t.a,{href:"https://github.com/github/codeql-cli-binaries",children:"repo"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},7226:(e,t,i)=>{i.d(t,{A:()=>s});const s=i.p+"assets/images/output-1649b3fc1ffdce14d0b6295e84a7b9aa.gif"},1503:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>d});var s=i(758);const o={},n=s.createContext(o);function r(e){const t=s.useContext(n);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/649e0194.528b489b.js b/assets/js/649e0194.528b489b.js new file mode 100644 index 0000000..de77456 --- /dev/null +++ b/assets/js/649e0194.528b489b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[789],{4763:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var t=n(6070),a=n(1503);const o={},s=void 0,c={id:"README/det01_doc",title:"det01_doc",description:"transferFrom uses arbitrary from",source:"@site/docs/README/det01_doc.md",sourceDirName:"README",slug:"/README/det01_doc",permalink:"/CyScout/docs/README/det01_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det01_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"CyScout",permalink:"/CyScout/docs/README/"},next:{title:"det02_doc",permalink:"/CyScout/docs/README/det02_doc"}},d={},i=[{value:"transferFrom uses arbitrary from",id:"transferfrom-uses-arbitrary-from",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function l(e){const r={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(r.h2,{id:"transferfrom-uses-arbitrary-from",children:["transferFrom uses arbitrary ",(0,t.jsx)(r.code,{children:"from"})]}),"\n",(0,t.jsx)(r.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector1.ql -d /path-to-database/\n"})}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["Based on the ",(0,t.jsx)(r.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom",children:"arbitrary-send-erc20"})," detector from Slither.\nDetects wrongful usage of an arbitrary ",(0,t.jsx)(r.code,{children:"from"})," variable\nin a transfer call."]}),"\n",(0,t.jsx)(r.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,t.jsxs)(r.p,{children:["Use ",(0,t.jsx)(r.code,{children:"msg.sender"})," instead."]}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(from, to, amount);\n }\n}\n"})}),"\n",(0,t.jsx)(r.h3,{id:"fixed",children:"Fixed"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(msg.sender, to, amount);\n }\n}\n"})})]})}function u(e={}){const{wrapper:r}={...(0,a.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1503:(e,r,n)=>{n.d(r,{R:()=>s,x:()=>c});var t=n(758);const a={},o=t.createContext(a);function s(e){const r=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function c(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),t.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/649e0194.b045397c.js b/assets/js/649e0194.b045397c.js deleted file mode 100644 index 101a463..0000000 --- a/assets/js/649e0194.b045397c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[789],{4763:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>c,toc:()=>i});var t=n(6070),a=n(1503);const s={},o=void 0,c={id:"README/det01_doc",title:"det01_doc",description:"transferFrom uses arbitrary from",source:"@site/docs/README/det01_doc.md",sourceDirName:"README",slug:"/README/det01_doc",permalink:"/docs/README/det01_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det01_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"CyScout",permalink:"/docs/README/"},next:{title:"det02_doc",permalink:"/docs/README/det02_doc"}},d={},i=[{value:"transferFrom uses arbitrary from",id:"transferfrom-uses-arbitrary-from",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function l(e){const r={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(r.h2,{id:"transferfrom-uses-arbitrary-from",children:["transferFrom uses arbitrary ",(0,t.jsx)(r.code,{children:"from"})]}),"\n",(0,t.jsx)(r.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector1.ql -d /path-to-database/\n"})}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["Based on the ",(0,t.jsx)(r.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom",children:"arbitrary-send-erc20"})," detector from Slither.\nDetects wrongful usage of an arbitrary ",(0,t.jsx)(r.code,{children:"from"})," variable\nin a transfer call."]}),"\n",(0,t.jsx)(r.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,t.jsxs)(r.p,{children:["Use ",(0,t.jsx)(r.code,{children:"msg.sender"})," instead."]}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(from, to, amount);\n }\n}\n"})}),"\n",(0,t.jsx)(r.h3,{id:"fixed",children:"Fixed"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(msg.sender, to, amount);\n }\n}\n"})})]})}function u(e={}){const{wrapper:r}={...(0,a.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1503:(e,r,n)=>{n.d(r,{R:()=>o,x:()=>c});var t=n(758);const a={},s=t.createContext(a);function o(e){const r=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function c(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/68781f40.0a3d27ed.js b/assets/js/68781f40.0a3d27ed.js new file mode 100644 index 0000000..d6a73ff --- /dev/null +++ b/assets/js/68781f40.0a3d27ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[669],{323:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var r=n(6070),c=n(1503);const s={},i=void 0,o={id:"Detectors/incorrect-shift",title:"incorrect-shift",description:"Incorrect shift in assembly",source:"@site/docs/Detectors/incorrect-shift.md",sourceDirName:"Detectors",slug:"/Detectors/incorrect-shift",permalink:"/CyScout/docs/Detectors/incorrect-shift",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/incorrect-shift.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Incorrect exponentiation",permalink:"/CyScout/docs/Detectors/incorrect-exp"},next:{title:"is-unreachable",permalink:"/CyScout/docs/Detectors/is-unreachable"}},a={},l=[{value:"Incorrect shift in assembly",id:"incorrect-shift-in-assembly",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"incorrect-shift-in-assembly",children:"Incorrect shift in assembly"}),"\n",(0,r.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/slither-bitshift-order.ql -d /path-to-database/\n"})}),"\n",(0,r.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(t.p,{children:["Based on Slither's ",(0,r.jsx)(t.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-shift-in-assembly",children:"incorrect-shift detector"}),".\nDetects if the values in a shift operation are reversed."]}),"\n",(0,r.jsx)(t.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,r.jsx)(t.p,{children:"Invert the order of call arguments\nto correctly perform the shift operation."}),"\n",(0,r.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(t.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(a, 8)\n }\n }\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"fixed",children:"Fixed"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(8, a)\n }\n }\n}\n"})})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1503:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var r=n(758);const c={},s=r.createContext(c);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/68781f40.2a400fd6.js b/assets/js/68781f40.2a400fd6.js deleted file mode 100644 index 1c828d4..0000000 --- a/assets/js/68781f40.2a400fd6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[669],{323:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var r=n(6070),s=n(1503);const i={},c=void 0,o={id:"Detectors/incorrect-shift",title:"incorrect-shift",description:"Incorrect shift in assembly",source:"@site/docs/Detectors/incorrect-shift.md",sourceDirName:"Detectors",slug:"/Detectors/incorrect-shift",permalink:"/docs/Detectors/incorrect-shift",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/incorrect-shift.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Incorrect exponentiation",permalink:"/docs/Detectors/incorrect-exp"},next:{title:"is-unreachable",permalink:"/docs/Detectors/is-unreachable"}},a={},l=[{value:"Incorrect shift in assembly",id:"incorrect-shift-in-assembly",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"incorrect-shift-in-assembly",children:"Incorrect shift in assembly"}),"\n",(0,r.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/slither-bitshift-order.ql -d /path-to-database/\n"})}),"\n",(0,r.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(t.p,{children:["Based on Slither's ",(0,r.jsx)(t.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-shift-in-assembly",children:"incorrect-shift detector"}),".\nDetects if the values in a shift operation are reversed."]}),"\n",(0,r.jsx)(t.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,r.jsx)(t.p,{children:"Invert the order of call arguments\nto correctly perform the shift operation."}),"\n",(0,r.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(t.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(a, 8)\n }\n }\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"fixed",children:"Fixed"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(8, a)\n }\n }\n}\n"})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1503:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>o});var r=n(758);const s={},i=r.createContext(s);function c(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/69f4f467.61eac5ae.js b/assets/js/69f4f467.61eac5ae.js new file mode 100644 index 0000000..982a967 --- /dev/null +++ b/assets/js/69f4f467.61eac5ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[405],{6124:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>d,toc:()=>a});var c=t(6070),r=t(1503);const s={},o="Unchecked Send",d={id:"Detectors/unchecked-send",title:"Unchecked Send",description:"Description",source:"@site/docs/Detectors/unchecked-send.md",sourceDirName:"Detectors",slug:"/Detectors/unchecked-send",permalink:"/CyScout/docs/Detectors/unchecked-send",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/unchecked-send.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"transfer-from",permalink:"/CyScout/docs/Detectors/transfer-from"},next:{title:"Unrpotected self destruct",permalink:"/CyScout/docs/Detectors/unprotected-self-destruct"}},i={},a=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"unchecked-send",children:"Unchecked Send"})}),"\n",(0,c.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,c.jsxs)(n.p,{children:["Based on Slither's ",(0,c.jsx)(n.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-send",children:"unchecked-send detector"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"The return value of a send is not checked."}),"\n",(0,c.jsx)(n.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"contract MyConc{\n function my_func(address payable dst) public payable{\n dst.send(msg.value);\n }\n}\n"})}),"\n",(0,c.jsx)(n.p,{children:"The return value of send is not checked, so if the send fails, the Ether will be locked in the contract. If send is used to prevent blocking operations, consider logging the failed send."}),"\n",(0,c.jsx)(n.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,c.jsx)(n.p,{children:"Ensure that the return value of send is checked or logged."})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var c=t(758);const r={},s=c.createContext(r);function o(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/69f4f467.8a9e2f1c.js b/assets/js/69f4f467.8a9e2f1c.js deleted file mode 100644 index c883da7..0000000 --- a/assets/js/69f4f467.8a9e2f1c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[405],{6124:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>a});var c=t(6070),r=t(1503);const s={},o="Unchecked Send",d={id:"Detectors/unchecked-send",title:"Unchecked Send",description:"Description",source:"@site/docs/Detectors/unchecked-send.md",sourceDirName:"Detectors",slug:"/Detectors/unchecked-send",permalink:"/docs/Detectors/unchecked-send",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/unchecked-send.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"transfer-from",permalink:"/docs/Detectors/transfer-from"},next:{title:"Unrpotected self destruct",permalink:"/docs/Detectors/unprotected-self-destruct"}},i={},a=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"unchecked-send",children:"Unchecked Send"})}),"\n",(0,c.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,c.jsxs)(n.p,{children:["Based on Slither's ",(0,c.jsx)(n.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-send",children:"unchecked-send detector"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"The return value of a send is not checked."}),"\n",(0,c.jsx)(n.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"contract MyConc{\n function my_func(address payable dst) public payable{\n dst.send(msg.value);\n }\n}\n"})}),"\n",(0,c.jsx)(n.p,{children:"The return value of send is not checked, so if the send fails, the Ether will be locked in the contract. If send is used to prevent blocking operations, consider logging the failed send."}),"\n",(0,c.jsx)(n.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,c.jsx)(n.p,{children:"Ensure that the return value of send is checked or logged."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var c=t(758);const r={},s=c.createContext(r);function o(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6b120e63.306a885e.js b/assets/js/6b120e63.306a885e.js deleted file mode 100644 index 65bf4fa..0000000 --- a/assets/js/6b120e63.306a885e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[962],{6842:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>o});var a=t(6070),r=t(1503);const c={},s=void 0,i={id:"Detectors/is-unreachable",title:"is-unreachable",description:"Is unreachable",source:"@site/docs/Detectors/is-unreachable.md",sourceDirName:"Detectors",slug:"/Detectors/is-unreachable",permalink:"/docs/Detectors/is-unreachable",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/is-unreachable.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"incorrect-shift",permalink:"/docs/Detectors/incorrect-shift"},next:{title:"msg-value-in-for-loop",permalink:"/docs/Detectors/msg-value-in-for-loop"}},l={},o=[{value:"Is unreachable",id:"is-unreachable",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function d(e){const n={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"is-unreachable",children:"Is unreachable"}),"\n",(0,a.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/is-unreachable.ql -d /path-to-database/\n"})}),"\n",(0,a.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,a.jsx)(n.p,{children:"Detects dead code on a CFG level, in the form of unreachable basic blocks."}),"\n",(0,a.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,a.jsx)(n.p,{children:"Eliminate code that can't be executed and thus has no effect in\nthe logic of the final program."}),"\n",(0,a.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n if(false)\n {\n revert();\n }\n }\n}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"fixed",children:"Fixed"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n // if(false)\n {\n revert();\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var a=t(758);const r={},c=a.createContext(r);function s(e){const n=a.useContext(c);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6b120e63.9d6cfb69.js b/assets/js/6b120e63.9d6cfb69.js new file mode 100644 index 0000000..2aeb4a9 --- /dev/null +++ b/assets/js/6b120e63.9d6cfb69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[962],{6842:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var c=t(6070),a=t(1503);const r={},s=void 0,i={id:"Detectors/is-unreachable",title:"is-unreachable",description:"Is unreachable",source:"@site/docs/Detectors/is-unreachable.md",sourceDirName:"Detectors",slug:"/Detectors/is-unreachable",permalink:"/CyScout/docs/Detectors/is-unreachable",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/is-unreachable.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"incorrect-shift",permalink:"/CyScout/docs/Detectors/incorrect-shift"},next:{title:"msg-value-in-for-loop",permalink:"/CyScout/docs/Detectors/msg-value-in-for-loop"}},l={},o=[{value:"Is unreachable",id:"is-unreachable",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function d(e){const n={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h2,{id:"is-unreachable",children:"Is unreachable"}),"\n",(0,c.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/is-unreachable.ql -d /path-to-database/\n"})}),"\n",(0,c.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,c.jsx)(n.p,{children:"Detects dead code on a CFG level, in the form of unreachable basic blocks."}),"\n",(0,c.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,c.jsx)(n.p,{children:"Eliminate code that can't be executed and thus has no effect in\nthe logic of the final program."}),"\n",(0,c.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,c.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n if(false)\n {\n revert();\n }\n }\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"fixed",children:"Fixed"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n // if(false)\n {\n revert();\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var c=t(758);const a={},r=c.createContext(a);function s(e){const n=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),c.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/74e2df82.54fea83f.js b/assets/js/74e2df82.54fea83f.js deleted file mode 100644 index 5fc3b03..0000000 --- a/assets/js/74e2df82.54fea83f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[235],{5698:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>o,frontMatter:()=>l,metadata:()=>d,toc:()=>t});var n=i(6070),r=i(1503);const l={},c="Access",d={id:"Classes/Access",title:"Access",description:"Classes",source:"@site/docs/Classes/Access.md",sourceDirName:"Classes",slug:"/Classes/Access",permalink:"/docs/Classes/Access",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Access.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",next:{title:"BasicBlock",permalink:"/docs/Classes/BasicBlock"}},a={},t=[{value:"Classes",id:"classes",level:2},{value:"Predicates",id:"predicates",level:2},{value:"Access",id:"access-1",level:2},{value:"Methods",id:"methods",level:3},{value:"Access ()",id:"access-",level:3},{value:"getTarget()",id:"gettarget",level:3},{value:"mayBeImpure()",id:"maybeimpure",level:3},{value:"mayBeGloballyImpure()",id:"maybegloballyimpure",level:3},{value:"toString()",id:"tostring",level:3},{value:"VariableAccess",id:"variableaccess",level:2},{value:"Methods and predicates",id:"methods-and-predicates",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"getTarget()",id:"gettarget-1",level:3},{value:"isUsedAsLValue()",id:"isusedaslvalue",level:3},{value:"isModified()",id:"ismodified",level:3},{value:"isRValue()",id:"isrvalue",level:3},{value:"getQualifier()",id:"getqualifier",level:3},{value:"toString()",id:"tostring-1",level:3},{value:"mayBeImpure()",id:"maybeimpure-1",level:3},{value:"mayBeGloballyImpure()",id:"maybegloballyimpure-1",level:3},{value:"isAddressOfAccess()",id:"isaddressofaccess",level:3},{value:"isAddressOfAccessNonConst()",id:"isaddressofaccessnonconst",level:3},{value:"FieldAccess",id:"fieldaccess",level:2},{value:"Methods",id:"methods-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"FieldAccess()",id:"fieldaccess-1",level:3},{value:"getTarget()",id:"gettarget-2",level:3},{value:"PointerFieldAccess",id:"pointerfieldaccess",level:2},{value:"Methods",id:"methods-2",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"PointerFieldAccess()",id:"pointerfieldaccess-1",level:3},{value:"DotFieldAccess",id:"dotfieldaccess",level:2},{value:"Methods",id:"methods-3",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3},{value:"DotFieldAccess()",id:"dotfieldaccess-1",level:3},{value:"ReferenceFieldAccess",id:"referencefieldaccess",level:2},{value:"Methods",id:"methods-4",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-4",level:3},{value:"ReferenceFieldAccess()",id:"referencefieldaccess-1",level:3},{value:"ValueFieldAccess",id:"valuefieldaccess",level:2},{value:"Methods",id:"methods-5",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-5",level:3},{value:"ValueFieldAccess()",id:"valuefieldaccess-1",level:3},{value:"TypeName",id:"typename",level:2},{value:"referenceConversion(Conversion c)",id:"referenceconversionconversion-c",level:2},{value:"exprHasReferenceConversion(Expr e)",id:"exprhasreferenceconversionexpr-e",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"access",children:"Access"})}),"\n",(0,n.jsx)(s.h2,{id:"classes",children:"Classes"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#access",children:"Access"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#variableaccess",children:"VariableAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#fieldaccess",children:"FieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#pointerfieldaccess",children:"PointerFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#dotfieldaccess",children:"DotFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#referencefieldaccess",children:"ReferenceFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#valuefieldaccess",children:"ValueFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#typename",children:"TypeName"})}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"predicates",children:"Predicates"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#referenceconversionconversion-c",children:"referenceConversion(Conversion c)"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#exprhasreferenceconversionexpr-e",children:"exprHasReferenceConversion(Expr e)"})}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"access-1",children:"Access"}),"\n",(0,n.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#access-",children:"Access()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#gettarget",children:"getTarget()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybeimpure",children:"mayBeImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybegloballyimpure",children:"mayBeGloballyImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#tostring",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"access-",children:"Access ()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Access() { this instanceof Solidity::AssignmentExpression or \n this instanceof Solidity::AugmentedAssignmentExpression or\n this instanceof Solidity::EnumValue or\n this instanceof Solidity::EnumDeclaration or\n this instanceof Solidity::VariableDeclaration\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"gettarget",children:"getTarget()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Declaration getTarget() { none() } // overridden in subclasses\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the accessed function, variable, or enum constant."}),"\n",(0,n.jsx)(s.h3,{id:"maybeimpure",children:"mayBeImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate mayBeImpure() { none() }\n"})}),"\n",(0,n.jsx)(s.h3,{id:"maybegloballyimpure",children:"mayBeGloballyImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate mayBeGloballyImpure() { none() }\n"})}),"\n",(0,n.jsx)(s.h3,{id:"tostring",children:"toString()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override string toString() { none() }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"variableaccess",children:"VariableAccess"}),"\n",(0,n.jsx)(s.h3,{id:"methods-and-predicates",children:"Methods and predicates"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#gettarget-1",children:"getTarget()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isusedaslvalue",children:"isUsedAsLValue()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#ismodified",children:"isModified()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isrvalue",children:"isRValue()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getqualifier",children:"getQualifier()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#tostring-1",children:"toString()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybeimpure-1",children:"mayBeImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybegloballyimpure-1",children:"mayBeGloballyImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isaddressofaccess",children:"isAddressOfAccess()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isaddressofaccessnonconst",children:"isAddressOfAccessNonConst()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "VariableAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"gettarget-1",children:"getTarget()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override Variable getTarget() { varbind(underlyingElement(this), unresolveElement(result)) }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the accessed variable."}),"\n",(0,n.jsx)(s.h3,{id:"isusedaslvalue",children:"isUsedAsLValue()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isUsedAsLValue() {\n exists(Assignment a | a.getLValue() = this) or\n exists(CrementOperation c | c.getOperand() = this) \n}\n"})}),"\n",(0,n.jsx)(s.p,{children:"Holds if this variable access is providing an LValue in a meaningful way.\nFor example, this includes accesses on the left-hand side of an assignment.\nIt does not include accesses on the right-hand side of an assignment, even if they could appear on the left-hand side of some assignment."}),"\n",(0,n.jsx)(s.h3,{id:"ismodified",children:"isModified()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:" predicate isModified() {\n exists(Solidity::AssignmentExpression a | a.getLeft().getChild() = )\n or\n exists(CrementOperation c | c.getOperand() = this)\n}\n"})}),"\n",(0,n.jsx)(s.p,{children:"Holds if this variable access is in a position where it is (directly) modified,\nfor instance by an assignment or increment/decrement operator."}),"\n",(0,n.jsx)(s.h3,{id:"isrvalue",children:"isRValue()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isRValue() {\n not exists(AssignExpr ae | ae.getLValue() = this) and\n not exists(AddressOfExpr addof | addof.getOperand() = this) and\n not this.getConversion() instanceof ReferenceToExpr and\n not this.getConversion() instanceof ArrayToPointerConversion\n}\n"})}),"\n",(0,n.jsx)(s.p,{children:"Holds if this variable access is an rvalue."}),"\n",(0,n.jsx)(s.h3,{id:"getqualifier",children:"getQualifier()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Expr getQualifier() { this.getChild(-1) = result }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the expression generating the variable being accessed."}),"\n",(0,n.jsxs)(s.p,{children:["As a few examples:\nFor ",(0,n.jsx)(s.code,{children:"ptr->x"}),", this gives ",(0,n.jsx)(s.code,{children:"ptr"}),".\nFor ",(0,n.jsx)(s.code,{children:"(*ptr).x"}),", this gives ",(0,n.jsx)(s.code,{children:"(*ptr)"}),".\nFor ",(0,n.jsx)(s.code,{children:"smart_ptr->x"}),", this gives the call to ",(0,n.jsx)(s.code,{children:"operator->"}),"."]}),"\n",(0,n.jsx)(s.p,{children:'This applies mostly to FieldAccesses, but also to static member variables accessed\n"through" a pointer. Note that it does NOT apply to static member variables accessed\nthrough a type name, as in that case the type name is a qualifier on the variable\nrather than a qualifier on the access.'}),"\n",(0,n.jsx)(s.h3,{id:"tostring-1",children:"toString()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string toString() {\n if exists(this.getTarget())\n then result = this.getTarget().getName()\n else result = "variable access"\n}\n'})}),"\n",(0,n.jsx)(s.p,{children:"Gets a textual representation of this variable access."}),"\n",(0,n.jsx)(s.h3,{id:"maybeimpure-1",children:"mayBeImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:" override predicate mayBeImpure() {\n this.getQualifier().mayBeImpure() or\n this.getTarget().getType().isVolatile()\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"maybegloballyimpure-1",children:"mayBeGloballyImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override predicate mayBeGloballyImpure() {\n this.getQualifier().mayBeGloballyImpure() or\n this.getTarget().getType().isVolatile()\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"isaddressofaccess",children:"isAddressOfAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isAddressOfAccess() { variableAddressEscapesTree(this, _) }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if this access is used to get the address of the underlying variable\nin such a way that the address might escape. This can be either explicit,\nfor example ",(0,n.jsx)(s.code,{children:"&x"}),", or implicit, for example ",(0,n.jsx)(s.code,{children:"T& y = x"}),"."]}),"\n",(0,n.jsx)(s.h3,{id:"isaddressofaccessnonconst",children:"isAddressOfAccessNonConst()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isAddressOfAccessNonConst() { variableAddressEscapesTreeNonConst(this, _) }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if this access is used to get the address of the underlying variable in such a way that the address might escape as a pointer or reference to non-const data. This can be either explicit, for example ",(0,n.jsx)(s.code,{children:"&x"}),", or implicit, for example ",(0,n.jsx)(s.code,{children:"T& y = x"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"fieldaccess",children:"FieldAccess"}),"\n",(0,n.jsx)(s.h3,{id:"methods-1",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#fieldaccess-1",children:"FieldAccess()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#gettarget-2",children:"getTarget()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "FieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"fieldaccess-1",children:"FieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"FieldAccess() { exists(Field f | varbind(underlyingElement(this), unresolveElement(f))) }\n"})}),"\n",(0,n.jsx)(s.h3,{id:"gettarget-2",children:"getTarget()"}),"\n",(0,n.jsx)(s.p,{children:"Gets the accessed field."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override Field getTarget() { result = super.getTarget() }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"pointerfieldaccess",children:"PointerFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access whose qualifier is a pointer to a class, struct or union.\nThese typically take the form ",(0,n.jsx)(s.code,{children:"obj->field"}),". Another case is a field access\nwith an implicit ",(0,n.jsx)(s.code,{children:"this->"})," qualifier, which is often a ",(0,n.jsx)(s.code,{children:"PointerFieldAccess"}),"\n(but see also ",(0,n.jsx)(s.code,{children:"ImplicitThisFieldAccess"}),")."]}),"\n",(0,n.jsxs)(s.p,{children:["For example the accesses to ",(0,n.jsx)(s.code,{children:"x"})," and ",(0,n.jsx)(s.code,{children:"y"})," in ",(0,n.jsx)(s.code,{children:"myMethod"})," in the following code\nare each a ",(0,n.jsx)(s.code,{children:"PointerFieldAccess"}),":"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"class MyClass {\npublic:\n void myMethod(MyClass *other) {\n other->x = y;\n }\n *\n int x, y;\n};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"methods-2",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-2",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#pointerfieldaccess-1",children:"PointerFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "PointerFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"pointerfieldaccess-1",children:"PointerFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"PointerFieldAccess() {\n exists(PointerType t |\n t = this.getQualifier().getFullyConverted().getUnspecifiedType() and\n t.getBaseType() instanceof Class\n )\n}\n"})}),"\n",(0,n.jsx)(s.h2,{id:"dotfieldaccess",children:"DotFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access of the form ",(0,n.jsx)(s.code,{children:"obj.field"}),". The type of ",(0,n.jsx)(s.code,{children:"obj"})," is either a\nclass/struct/union or a reference to one. ",(0,n.jsx)(s.code,{children:"DotFieldAccess"})," has two\nsub-classes, ",(0,n.jsx)(s.code,{children:"ValueFieldAccess"})," and ",(0,n.jsx)(s.code,{children:"ReferenceFieldAccess"}),", to\ndistinguish whether or not the type of ",(0,n.jsx)(s.code,{children:"obj"})," is a reference type."]}),"\n",(0,n.jsx)(s.h3,{id:"methods-3",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-3",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#dotfieldaccess-1",children:"DotFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "DotFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"dotfieldaccess-1",children:"DotFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"DotFieldAccess() { this.getQualifier().getFullyConverted().getUnspecifiedType() instanceof Class }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"referencefieldaccess",children:"ReferenceFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access of the form ",(0,n.jsx)(s.code,{children:"obj.field"}),", where the type of ",(0,n.jsx)(s.code,{children:"obj"})," is a\nreference to a class/struct/union. For example the accesses to ",(0,n.jsx)(s.code,{children:"y"})," in\n",(0,n.jsx)(s.code,{children:"myMethod"})," in the following code:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"class MyClass {\npublic:\n void myMethod(MyClass a, MyClass &b) {\n a.x = b.y;\n }\n *\n int x, y;\n};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"methods-4",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-4",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#referencefieldaccess-1",children:"ReferenceFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-4",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "ReferenceFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"referencefieldaccess-1",children:"ReferenceFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ReferenceFieldAccess() { exprHasReferenceConversion(this.getQualifier()) }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"valuefieldaccess",children:"ValueFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access of the form ",(0,n.jsx)(s.code,{children:"obj.field"}),", where the type of ",(0,n.jsx)(s.code,{children:"obj"})," is a\nclass/struct/union (and not a reference). For example the accesses to ",(0,n.jsx)(s.code,{children:"x"}),"\nin ",(0,n.jsx)(s.code,{children:"myMethod"})," in the following code:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"class MyClass {\npublic:\n void myMethod(MyClass a, MyClass &b) {\n a.x = b.y;\n }\n\n int x, y;\n};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"methods-5",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-5",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#valuefieldaccess-1",children:"ValueFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-5",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "ValueFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"valuefieldaccess-1",children:"ValueFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ValueFieldAccess() { not exprHasReferenceConversion(this.getQualifier()) }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"typename",children:"TypeName"}),"\n",(0,n.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,n.jsx)(s.h2,{id:"referenceconversionconversion-c",children:"referenceConversion(Conversion c)"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"private predicate referenceConversion(Conversion c) {\n c.getType() = c.getExpr().getType().(ReferenceType).getBaseType()\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if ",(0,n.jsx)(s.code,{children:"c"})," is a conversion from type ",(0,n.jsx)(s.code,{children:"T&"})," to ",(0,n.jsx)(s.code,{children:"T"})," (or from ",(0,n.jsx)(s.code,{children:"T&&"})," to ",(0,n.jsx)(s.code,{children:"T"}),")."]}),"\n",(0,n.jsx)(s.h2,{id:"exprhasreferenceconversionexpr-e",children:"exprHasReferenceConversion(Expr e)"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"private predicate exprHasReferenceConversion(Expr e) { referenceConversion(e.getConversion+()) }\n\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if ",(0,n.jsx)(s.code,{children:"e"})," is a reference expression (that is, it has a type of the form ",(0,n.jsx)(s.code,{children:"T&"}),"), which is converted to a value. For example:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"int myfcn(MyStruct &x) {\n return x.field;\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["In this example, the type of ",(0,n.jsx)(s.code,{children:"x"})," is ",(0,n.jsx)(s.code,{children:"MyStruct&"}),", but it gets implicitly converted to ",(0,n.jsx)(s.code,{children:"MyStruct"})," in the expression ",(0,n.jsx)(s.code,{children:"x.field"}),"."]})]})}function o(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1503:(e,s,i)=>{i.d(s,{R:()=>c,x:()=>d});var n=i(758);const r={},l=n.createContext(r);function c(e){const s=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(l.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/74e2df82.eb367e96.js b/assets/js/74e2df82.eb367e96.js new file mode 100644 index 0000000..a6e1236 --- /dev/null +++ b/assets/js/74e2df82.eb367e96.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[235],{5698:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>o,frontMatter:()=>l,metadata:()=>d,toc:()=>t});var n=i(6070),r=i(1503);const l={},c="Access",d={id:"Classes/Access",title:"Access",description:"Classes",source:"@site/docs/Classes/Access.md",sourceDirName:"Classes",slug:"/Classes/Access",permalink:"/CyScout/docs/Classes/Access",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Access.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",next:{title:"BasicBlock",permalink:"/CyScout/docs/Classes/BasicBlock"}},a={},t=[{value:"Classes",id:"classes",level:2},{value:"Predicates",id:"predicates",level:2},{value:"Access",id:"access-1",level:2},{value:"Methods",id:"methods",level:3},{value:"Access ()",id:"access-",level:3},{value:"getTarget()",id:"gettarget",level:3},{value:"mayBeImpure()",id:"maybeimpure",level:3},{value:"mayBeGloballyImpure()",id:"maybegloballyimpure",level:3},{value:"toString()",id:"tostring",level:3},{value:"VariableAccess",id:"variableaccess",level:2},{value:"Methods and predicates",id:"methods-and-predicates",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"getTarget()",id:"gettarget-1",level:3},{value:"isUsedAsLValue()",id:"isusedaslvalue",level:3},{value:"isModified()",id:"ismodified",level:3},{value:"isRValue()",id:"isrvalue",level:3},{value:"getQualifier()",id:"getqualifier",level:3},{value:"toString()",id:"tostring-1",level:3},{value:"mayBeImpure()",id:"maybeimpure-1",level:3},{value:"mayBeGloballyImpure()",id:"maybegloballyimpure-1",level:3},{value:"isAddressOfAccess()",id:"isaddressofaccess",level:3},{value:"isAddressOfAccessNonConst()",id:"isaddressofaccessnonconst",level:3},{value:"FieldAccess",id:"fieldaccess",level:2},{value:"Methods",id:"methods-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"FieldAccess()",id:"fieldaccess-1",level:3},{value:"getTarget()",id:"gettarget-2",level:3},{value:"PointerFieldAccess",id:"pointerfieldaccess",level:2},{value:"Methods",id:"methods-2",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"PointerFieldAccess()",id:"pointerfieldaccess-1",level:3},{value:"DotFieldAccess",id:"dotfieldaccess",level:2},{value:"Methods",id:"methods-3",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3},{value:"DotFieldAccess()",id:"dotfieldaccess-1",level:3},{value:"ReferenceFieldAccess",id:"referencefieldaccess",level:2},{value:"Methods",id:"methods-4",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-4",level:3},{value:"ReferenceFieldAccess()",id:"referencefieldaccess-1",level:3},{value:"ValueFieldAccess",id:"valuefieldaccess",level:2},{value:"Methods",id:"methods-5",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-5",level:3},{value:"ValueFieldAccess()",id:"valuefieldaccess-1",level:3},{value:"TypeName",id:"typename",level:2},{value:"referenceConversion(Conversion c)",id:"referenceconversionconversion-c",level:2},{value:"exprHasReferenceConversion(Expr e)",id:"exprhasreferenceconversionexpr-e",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"access",children:"Access"})}),"\n",(0,n.jsx)(s.h2,{id:"classes",children:"Classes"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#access",children:"Access"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#variableaccess",children:"VariableAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#fieldaccess",children:"FieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#pointerfieldaccess",children:"PointerFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#dotfieldaccess",children:"DotFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#referencefieldaccess",children:"ReferenceFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#valuefieldaccess",children:"ValueFieldAccess"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#typename",children:"TypeName"})}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"predicates",children:"Predicates"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#referenceconversionconversion-c",children:"referenceConversion(Conversion c)"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#exprhasreferenceconversionexpr-e",children:"exprHasReferenceConversion(Expr e)"})}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"access-1",children:"Access"}),"\n",(0,n.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#access-",children:"Access()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#gettarget",children:"getTarget()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybeimpure",children:"mayBeImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybegloballyimpure",children:"mayBeGloballyImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#tostring",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"access-",children:"Access ()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Access() { this instanceof Solidity::AssignmentExpression or \n this instanceof Solidity::AugmentedAssignmentExpression or\n this instanceof Solidity::EnumValue or\n this instanceof Solidity::EnumDeclaration or\n this instanceof Solidity::VariableDeclaration\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"gettarget",children:"getTarget()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Declaration getTarget() { none() } // overridden in subclasses\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the accessed function, variable, or enum constant."}),"\n",(0,n.jsx)(s.h3,{id:"maybeimpure",children:"mayBeImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate mayBeImpure() { none() }\n"})}),"\n",(0,n.jsx)(s.h3,{id:"maybegloballyimpure",children:"mayBeGloballyImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate mayBeGloballyImpure() { none() }\n"})}),"\n",(0,n.jsx)(s.h3,{id:"tostring",children:"toString()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override string toString() { none() }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"variableaccess",children:"VariableAccess"}),"\n",(0,n.jsx)(s.h3,{id:"methods-and-predicates",children:"Methods and predicates"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#gettarget-1",children:"getTarget()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isusedaslvalue",children:"isUsedAsLValue()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#ismodified",children:"isModified()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isrvalue",children:"isRValue()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getqualifier",children:"getQualifier()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#tostring-1",children:"toString()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybeimpure-1",children:"mayBeImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#maybegloballyimpure-1",children:"mayBeGloballyImpure()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isaddressofaccess",children:"isAddressOfAccess()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#isaddressofaccessnonconst",children:"isAddressOfAccessNonConst()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "VariableAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"gettarget-1",children:"getTarget()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override Variable getTarget() { varbind(underlyingElement(this), unresolveElement(result)) }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the accessed variable."}),"\n",(0,n.jsx)(s.h3,{id:"isusedaslvalue",children:"isUsedAsLValue()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isUsedAsLValue() {\n exists(Assignment a | a.getLValue() = this) or\n exists(CrementOperation c | c.getOperand() = this) \n}\n"})}),"\n",(0,n.jsx)(s.p,{children:"Holds if this variable access is providing an LValue in a meaningful way.\nFor example, this includes accesses on the left-hand side of an assignment.\nIt does not include accesses on the right-hand side of an assignment, even if they could appear on the left-hand side of some assignment."}),"\n",(0,n.jsx)(s.h3,{id:"ismodified",children:"isModified()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:" predicate isModified() {\n exists(Solidity::AssignmentExpression a | a.getLeft().getChild() = )\n or\n exists(CrementOperation c | c.getOperand() = this)\n}\n"})}),"\n",(0,n.jsx)(s.p,{children:"Holds if this variable access is in a position where it is (directly) modified,\nfor instance by an assignment or increment/decrement operator."}),"\n",(0,n.jsx)(s.h3,{id:"isrvalue",children:"isRValue()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isRValue() {\n not exists(AssignExpr ae | ae.getLValue() = this) and\n not exists(AddressOfExpr addof | addof.getOperand() = this) and\n not this.getConversion() instanceof ReferenceToExpr and\n not this.getConversion() instanceof ArrayToPointerConversion\n}\n"})}),"\n",(0,n.jsx)(s.p,{children:"Holds if this variable access is an rvalue."}),"\n",(0,n.jsx)(s.h3,{id:"getqualifier",children:"getQualifier()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Expr getQualifier() { this.getChild(-1) = result }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the expression generating the variable being accessed."}),"\n",(0,n.jsxs)(s.p,{children:["As a few examples:\nFor ",(0,n.jsx)(s.code,{children:"ptr->x"}),", this gives ",(0,n.jsx)(s.code,{children:"ptr"}),".\nFor ",(0,n.jsx)(s.code,{children:"(*ptr).x"}),", this gives ",(0,n.jsx)(s.code,{children:"(*ptr)"}),".\nFor ",(0,n.jsx)(s.code,{children:"smart_ptr->x"}),", this gives the call to ",(0,n.jsx)(s.code,{children:"operator->"}),"."]}),"\n",(0,n.jsx)(s.p,{children:'This applies mostly to FieldAccesses, but also to static member variables accessed\n"through" a pointer. Note that it does NOT apply to static member variables accessed\nthrough a type name, as in that case the type name is a qualifier on the variable\nrather than a qualifier on the access.'}),"\n",(0,n.jsx)(s.h3,{id:"tostring-1",children:"toString()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string toString() {\n if exists(this.getTarget())\n then result = this.getTarget().getName()\n else result = "variable access"\n}\n'})}),"\n",(0,n.jsx)(s.p,{children:"Gets a textual representation of this variable access."}),"\n",(0,n.jsx)(s.h3,{id:"maybeimpure-1",children:"mayBeImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:" override predicate mayBeImpure() {\n this.getQualifier().mayBeImpure() or\n this.getTarget().getType().isVolatile()\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"maybegloballyimpure-1",children:"mayBeGloballyImpure()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override predicate mayBeGloballyImpure() {\n this.getQualifier().mayBeGloballyImpure() or\n this.getTarget().getType().isVolatile()\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"isaddressofaccess",children:"isAddressOfAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isAddressOfAccess() { variableAddressEscapesTree(this, _) }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if this access is used to get the address of the underlying variable\nin such a way that the address might escape. This can be either explicit,\nfor example ",(0,n.jsx)(s.code,{children:"&x"}),", or implicit, for example ",(0,n.jsx)(s.code,{children:"T& y = x"}),"."]}),"\n",(0,n.jsx)(s.h3,{id:"isaddressofaccessnonconst",children:"isAddressOfAccessNonConst()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isAddressOfAccessNonConst() { variableAddressEscapesTreeNonConst(this, _) }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if this access is used to get the address of the underlying variable in such a way that the address might escape as a pointer or reference to non-const data. This can be either explicit, for example ",(0,n.jsx)(s.code,{children:"&x"}),", or implicit, for example ",(0,n.jsx)(s.code,{children:"T& y = x"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"fieldaccess",children:"FieldAccess"}),"\n",(0,n.jsx)(s.h3,{id:"methods-1",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#fieldaccess-1",children:"FieldAccess()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#gettarget-2",children:"getTarget()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "FieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"fieldaccess-1",children:"FieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"FieldAccess() { exists(Field f | varbind(underlyingElement(this), unresolveElement(f))) }\n"})}),"\n",(0,n.jsx)(s.h3,{id:"gettarget-2",children:"getTarget()"}),"\n",(0,n.jsx)(s.p,{children:"Gets the accessed field."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"override Field getTarget() { result = super.getTarget() }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"pointerfieldaccess",children:"PointerFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access whose qualifier is a pointer to a class, struct or union.\nThese typically take the form ",(0,n.jsx)(s.code,{children:"obj->field"}),". Another case is a field access\nwith an implicit ",(0,n.jsx)(s.code,{children:"this->"})," qualifier, which is often a ",(0,n.jsx)(s.code,{children:"PointerFieldAccess"}),"\n(but see also ",(0,n.jsx)(s.code,{children:"ImplicitThisFieldAccess"}),")."]}),"\n",(0,n.jsxs)(s.p,{children:["For example the accesses to ",(0,n.jsx)(s.code,{children:"x"})," and ",(0,n.jsx)(s.code,{children:"y"})," in ",(0,n.jsx)(s.code,{children:"myMethod"})," in the following code\nare each a ",(0,n.jsx)(s.code,{children:"PointerFieldAccess"}),":"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"class MyClass {\npublic:\n void myMethod(MyClass *other) {\n other->x = y;\n }\n *\n int x, y;\n};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"methods-2",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-2",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#pointerfieldaccess-1",children:"PointerFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "PointerFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"pointerfieldaccess-1",children:"PointerFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"PointerFieldAccess() {\n exists(PointerType t |\n t = this.getQualifier().getFullyConverted().getUnspecifiedType() and\n t.getBaseType() instanceof Class\n )\n}\n"})}),"\n",(0,n.jsx)(s.h2,{id:"dotfieldaccess",children:"DotFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access of the form ",(0,n.jsx)(s.code,{children:"obj.field"}),". The type of ",(0,n.jsx)(s.code,{children:"obj"})," is either a\nclass/struct/union or a reference to one. ",(0,n.jsx)(s.code,{children:"DotFieldAccess"})," has two\nsub-classes, ",(0,n.jsx)(s.code,{children:"ValueFieldAccess"})," and ",(0,n.jsx)(s.code,{children:"ReferenceFieldAccess"}),", to\ndistinguish whether or not the type of ",(0,n.jsx)(s.code,{children:"obj"})," is a reference type."]}),"\n",(0,n.jsx)(s.h3,{id:"methods-3",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-3",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#dotfieldaccess-1",children:"DotFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "DotFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"dotfieldaccess-1",children:"DotFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"DotFieldAccess() { this.getQualifier().getFullyConverted().getUnspecifiedType() instanceof Class }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"referencefieldaccess",children:"ReferenceFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access of the form ",(0,n.jsx)(s.code,{children:"obj.field"}),", where the type of ",(0,n.jsx)(s.code,{children:"obj"})," is a\nreference to a class/struct/union. For example the accesses to ",(0,n.jsx)(s.code,{children:"y"})," in\n",(0,n.jsx)(s.code,{children:"myMethod"})," in the following code:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"class MyClass {\npublic:\n void myMethod(MyClass a, MyClass &b) {\n a.x = b.y;\n }\n *\n int x, y;\n};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"methods-4",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-4",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#referencefieldaccess-1",children:"ReferenceFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-4",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "ReferenceFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"referencefieldaccess-1",children:"ReferenceFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ReferenceFieldAccess() { exprHasReferenceConversion(this.getQualifier()) }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"valuefieldaccess",children:"ValueFieldAccess"}),"\n",(0,n.jsxs)(s.p,{children:["A field access of the form ",(0,n.jsx)(s.code,{children:"obj.field"}),", where the type of ",(0,n.jsx)(s.code,{children:"obj"})," is a\nclass/struct/union (and not a reference). For example the accesses to ",(0,n.jsx)(s.code,{children:"x"}),"\nin ",(0,n.jsx)(s.code,{children:"myMethod"})," in the following code:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"class MyClass {\npublic:\n void myMethod(MyClass a, MyClass &b) {\n a.x = b.y;\n }\n\n int x, y;\n};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"methods-5",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getaprimaryqlclass-5",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#valuefieldaccess-1",children:"ValueFieldAccess()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getaprimaryqlclass-5",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "ValueFieldAccess" }\n'})}),"\n",(0,n.jsx)(s.h3,{id:"valuefieldaccess-1",children:"ValueFieldAccess()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ValueFieldAccess() { not exprHasReferenceConversion(this.getQualifier()) }\n"})}),"\n",(0,n.jsx)(s.h2,{id:"typename",children:"TypeName"}),"\n",(0,n.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,n.jsx)(s.h2,{id:"referenceconversionconversion-c",children:"referenceConversion(Conversion c)"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"private predicate referenceConversion(Conversion c) {\n c.getType() = c.getExpr().getType().(ReferenceType).getBaseType()\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if ",(0,n.jsx)(s.code,{children:"c"})," is a conversion from type ",(0,n.jsx)(s.code,{children:"T&"})," to ",(0,n.jsx)(s.code,{children:"T"})," (or from ",(0,n.jsx)(s.code,{children:"T&&"})," to ",(0,n.jsx)(s.code,{children:"T"}),")."]}),"\n",(0,n.jsx)(s.h2,{id:"exprhasreferenceconversionexpr-e",children:"exprHasReferenceConversion(Expr e)"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"private predicate exprHasReferenceConversion(Expr e) { referenceConversion(e.getConversion+()) }\n\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if ",(0,n.jsx)(s.code,{children:"e"})," is a reference expression (that is, it has a type of the form ",(0,n.jsx)(s.code,{children:"T&"}),"), which is converted to a value. For example:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"int myfcn(MyStruct &x) {\n return x.field;\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["In this example, the type of ",(0,n.jsx)(s.code,{children:"x"})," is ",(0,n.jsx)(s.code,{children:"MyStruct&"}),", but it gets implicitly converted to ",(0,n.jsx)(s.code,{children:"MyStruct"})," in the expression ",(0,n.jsx)(s.code,{children:"x.field"}),"."]})]})}function o(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1503:(e,s,i)=>{i.d(s,{R:()=>c,x:()=>d});var n=i(758);const r={},l=n.createContext(r);function c(e){const s=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(l.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79321e3a.bcf31eea.js b/assets/js/79321e3a.bcf31eea.js new file mode 100644 index 0000000..31b6997 --- /dev/null +++ b/assets/js/79321e3a.bcf31eea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[826],{5257:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var r=t(6070),c=t(1503);const s={},i=void 0,o={id:"README/det03_doc",title:"det03_doc",description:"Incorrect shift in assembly",source:"@site/docs/README/det03_doc.md",sourceDirName:"README",slug:"/README/det03_doc",permalink:"/CyScout/docs/README/det03_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det03_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"det02_doc",permalink:"/CyScout/docs/README/det02_doc"},next:{title:"det04_doc",permalink:"/CyScout/docs/README/det04_doc"}},a={},d=[{value:"Incorrect shift in assembly",id:"incorrect-shift-in-assembly",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"incorrect-shift-in-assembly",children:"Incorrect shift in assembly"}),"\n",(0,r.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector3.ql -d /path-to-database/\n"})}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:["Based on Slither's ",(0,r.jsx)(n.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-shift-in-assembly",children:"incorrect-shift detector"}),".\nDetects if the values in a shift operation are reversed."]}),"\n",(0,r.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,r.jsx)(n.p,{children:"Invert the order of call arguments\nto correctly perform the shift operation."}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(a, 8)\n }\n }\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"fixed",children:"Fixed"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(8, a)\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var r=t(758);const c={},s=r.createContext(c);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79321e3a.ea0fb1d6.js b/assets/js/79321e3a.ea0fb1d6.js deleted file mode 100644 index c5982a8..0000000 --- a/assets/js/79321e3a.ea0fb1d6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[826],{5257:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var r=t(6070),c=t(1503);const s={},i=void 0,a={id:"README/det03_doc",title:"det03_doc",description:"Incorrect shift in assembly",source:"@site/docs/README/det03_doc.md",sourceDirName:"README",slug:"/README/det03_doc",permalink:"/docs/README/det03_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det03_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"det02_doc",permalink:"/docs/README/det02_doc"},next:{title:"det04_doc",permalink:"/docs/README/det04_doc"}},o={},d=[{value:"Incorrect shift in assembly",id:"incorrect-shift-in-assembly",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"incorrect-shift-in-assembly",children:"Incorrect shift in assembly"}),"\n",(0,r.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector3.ql -d /path-to-database/\n"})}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:["Based on Slither's ",(0,r.jsx)(n.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-shift-in-assembly",children:"incorrect-shift detector"}),".\nDetects if the values in a shift operation are reversed."]}),"\n",(0,r.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,r.jsx)(n.p,{children:"Invert the order of call arguments\nto correctly perform the shift operation."}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(a, 8)\n }\n }\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"fixed",children:"Fixed"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"contract C {\n function f() internal returns (uint a) {\n assembly {\n a := shr(8, a)\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(758);const c={},s=r.createContext(c);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/796aa2a1.326ce302.js b/assets/js/796aa2a1.326ce302.js new file mode 100644 index 0000000..07714f6 --- /dev/null +++ b/assets/js/796aa2a1.326ce302.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[519],{4681:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>t,contentTitle:()=>l,default:()=>o,frontMatter:()=>n,metadata:()=>a,toc:()=>d});var c=s(6070),r=s(1503);const n={},l="Specifier",a={id:"Classes/Specifier",title:"Specifier",description:"Provides classes for modeling specifiers and attributes.",source:"@site/docs/Classes/Specifier.md",sourceDirName:"Classes",slug:"/Classes/Specifier",permalink:"/CyScout/docs/Classes/Specifier",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Specifier.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Function",permalink:"/CyScout/docs/Classes/Function"},next:{title:"SubBasicBlock",permalink:"/CyScout/docs/Classes/SubBasicBlock"}},t={},d=[{value:"Classes",id:"classes",level:2},{value:"Specifier",id:"specifier-1",level:2},{value:"Methods",id:"methods",level:3},{value:"Specifier()",id:"specifier-2",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"getName()",id:"getname",level:3},{value:"hasName(string name)",id:"hasnamestring-name",level:3},{value:"FunctionSpecifier",id:"functionspecifier",level:2},{value:"FunctionSpecifier()",id:"functionspecifier-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"StorageClassSpecifier",id:"storageclassspecifier",level:2},{value:"StorageClassSpecifier()",id:"storageclassspecifier-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"AccessSpecifier",id:"accessspecifier",level:2},{value:"AccessSpecifier()",id:"accessspecifier-1",level:3},{value:"accessInDirectDerived(AccessSpecifier baseAccess)",id:"accessindirectderivedaccessspecifier-baseaccess",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3}];function h(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i.header,{children:(0,c.jsx)(i.h1,{id:"specifier",children:"Specifier"})}),"\n",(0,c.jsx)(i.p,{children:"Provides classes for modeling specifiers and attributes."}),"\n",(0,c.jsx)(i.h2,{id:"classes",children:"Classes"}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#specifier-1",children:"Specifier"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#functionspecifier",children:"FunctionSpecifier"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#storageclassspecifier",children:"StorageClassSpecifier"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#accessspecifier",children:"AccessSpecifier"})}),"\n"]}),"\n",(0,c.jsx)(i.h2,{id:"specifier-1",children:"Specifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity specifier: ",(0,c.jsx)(i.code,{children:"internal"}),", ",(0,c.jsx)(i.code,{children:"public"}),", ",(0,c.jsx)(i.code,{children:"private"}),", ",(0,c.jsx)(i.code,{children:"external"}),", ",(0,c.jsx)(i.code,{children:"pure"}),", ",(0,c.jsx)(i.code,{children:"view"}),", ",(0,c.jsx)(i.code,{children:"immutable"}),", ",(0,c.jsx)(i.code,{children:"virtual"}),"."]}),"\n",(0,c.jsx)(i.h3,{id:"methods",children:"Methods"}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#specifier-2",children:"Specifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass",children:"getAPrimaryQlClass()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getname",children:"getName()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#hasnamestring-name",children:"hasName(string name)"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"specifier-2",children:"Specifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"Specifier(){this instanceof Solidity::StateMutability or this instanceof Solidity::Visibility\n or this instanceof Solidity::Virtual\n}\n"})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "Specifier" }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"getname",children:"getName()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"string getName() { result = this.(Solidity::Token).getValue().toString() }\n"})}),"\n",(0,c.jsx)(i.p,{children:"Gets the name of this specifier."}),"\n",(0,c.jsx)(i.h3,{id:"hasnamestring-name",children:"hasName(string name)"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"predicate hasName(string name) { name = this.getName() }\n"})}),"\n",(0,c.jsxs)(i.p,{children:["Holds if the name of this specifier is ",(0,c.jsx)(i.code,{children:"name"}),"."]}),"\n",(0,c.jsx)(i.h2,{id:"functionspecifier",children:"FunctionSpecifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity function specifier: ",(0,c.jsx)(i.code,{children:"inline"}),", ",(0,c.jsx)(i.code,{children:"virtual"}),", or ",(0,c.jsx)(i.code,{children:"explicit"}),"."]}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#functionspecifier-1",children:"FunctionSpecifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"functionspecifier-1",children:"FunctionSpecifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'FunctionSpecifier() { this.hasName(["inline", "virtual", "explicit"]) }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "FunctionSpecifier" }\n'})}),"\n",(0,c.jsx)(i.h2,{id:"storageclassspecifier",children:"StorageClassSpecifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity storage class specifier: ",(0,c.jsx)(i.code,{children:"auto"}),", ",(0,c.jsx)(i.code,{children:"register"}),", ",(0,c.jsx)(i.code,{children:"static"}),", ",(0,c.jsx)(i.code,{children:"extern"}),", or ",(0,c.jsx)(i.code,{children:"mutable"}),"."]}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#storageclassspecifier-1",children:"StorageClassSpecifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass-2",children:"getAPrimaryQlClass()"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"storageclassspecifier-1",children:"StorageClassSpecifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'StorageClassSpecifier() { this.hasName(["auto", "register", "static", "extern", "mutable"]) }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "StorageClassSpecifier" }\n'})}),"\n",(0,c.jsx)(i.h2,{id:"accessspecifier",children:"AccessSpecifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity access specifier: ",(0,c.jsx)(i.code,{children:"public"}),", ",(0,c.jsx)(i.code,{children:"private"}),", ",(0,c.jsx)(i.code,{children:"internal"}),", ",(0,c.jsx)(i.code,{children:"external"}),"."]}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#accessspecifier-1",children:"AccessSpecifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#accessindirectderivedaccessspecifier-baseaccess",children:"accessInDirectDerived(AccessSpecifier baseAccess)"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass-3",children:"getAPrimaryQlClass()"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"accessspecifier-1",children:"AccessSpecifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'AccessSpecifier() { this.hasName(["public", "private", "internal", "external"]) }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"accessindirectderivedaccessspecifier-baseaccess",children:"accessInDirectDerived(AccessSpecifier baseAccess)"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'AccessSpecifier accessInDirectDerived(AccessSpecifier baseAccess) {\n this.getName() != "private" and\n (\n // Alphabetically, "private" < "protected" < "public". This disjunction\n // encodes that `result` is the minimum access of `this` and\n // `baseAccess`.\n baseAccess.getName() < this.getName() and result = baseAccess\n or\n baseAccess.getName() >= this.getName() and result = this\n )\n }\n'})}),"\n",(0,c.jsxs)(i.p,{children:["Gets the visibility of a field with access specifier ",(0,c.jsx)(i.code,{children:"this"})," if it is\ndirectly inherited with access specifier ",(0,c.jsx)(i.code,{children:"baseAccess"}),". For example:"]}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"class A { protected int f; };\nclass B : private A {};\n"})}),"\n",(0,c.jsxs)(i.p,{children:["In this example, ",(0,c.jsx)(i.code,{children:"this"})," is ",(0,c.jsx)(i.code,{children:"protected"}),", ",(0,c.jsx)(i.code,{children:"baseAccess"})," is ",(0,c.jsx)(i.code,{children:"private"}),", and\n",(0,c.jsx)(i.code,{children:"result"})," is ",(0,c.jsx)(i.code,{children:"private"})," because the visibility of field ",(0,c.jsx)(i.code,{children:"f"})," in class ",(0,c.jsx)(i.code,{children:"B"}),"\nis ",(0,c.jsx)(i.code,{children:"private"}),"."]}),"\n",(0,c.jsx)(i.p,{children:"This method encodes the rules of N4140 11.2/1, tabulated here:"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"`this` | `baseAccess` | `result`\n(access in base) | (base class specifier) | (access in derived)\n----------------------------------------------------------\nprivate | private | N/A\nprivate | protected | N/A\nprivate | public | N/A\nprotected | private | private\nprotected | protected | protected\nprotected | public | protected\npublic | private | private\npublic | protected | protected\npublic | public | public\n"})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "AccessSpecifier" }\n'})})]})}function o(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,c.jsx)(i,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},1503:(e,i,s)=>{s.d(i,{R:()=>l,x:()=>a});var c=s(758);const r={},n=c.createContext(r);function l(e){const i=c.useContext(n);return c.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),c.createElement(n.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/796aa2a1.a61c5328.js b/assets/js/796aa2a1.a61c5328.js deleted file mode 100644 index 8d17ded..0000000 --- a/assets/js/796aa2a1.a61c5328.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[519],{4681:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>t,contentTitle:()=>l,default:()=>o,frontMatter:()=>n,metadata:()=>a,toc:()=>d});var c=s(6070),r=s(1503);const n={},l="Specifier",a={id:"Classes/Specifier",title:"Specifier",description:"Provides classes for modeling specifiers and attributes.",source:"@site/docs/Classes/Specifier.md",sourceDirName:"Classes",slug:"/Classes/Specifier",permalink:"/docs/Classes/Specifier",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Specifier.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Function",permalink:"/docs/Classes/Function"},next:{title:"SubBasicBlock",permalink:"/docs/Classes/SubBasicBlock"}},t={},d=[{value:"Classes",id:"classes",level:2},{value:"Specifier",id:"specifier-1",level:2},{value:"Methods",id:"methods",level:3},{value:"Specifier()",id:"specifier-2",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"getName()",id:"getname",level:3},{value:"hasName(string name)",id:"hasnamestring-name",level:3},{value:"FunctionSpecifier",id:"functionspecifier",level:2},{value:"FunctionSpecifier()",id:"functionspecifier-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"StorageClassSpecifier",id:"storageclassspecifier",level:2},{value:"StorageClassSpecifier()",id:"storageclassspecifier-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"AccessSpecifier",id:"accessspecifier",level:2},{value:"AccessSpecifier()",id:"accessspecifier-1",level:3},{value:"accessInDirectDerived(AccessSpecifier baseAccess)",id:"accessindirectderivedaccessspecifier-baseaccess",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3}];function h(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i.header,{children:(0,c.jsx)(i.h1,{id:"specifier",children:"Specifier"})}),"\n",(0,c.jsx)(i.p,{children:"Provides classes for modeling specifiers and attributes."}),"\n",(0,c.jsx)(i.h2,{id:"classes",children:"Classes"}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#specifier-1",children:"Specifier"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#functionspecifier",children:"FunctionSpecifier"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#storageclassspecifier",children:"StorageClassSpecifier"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#accessspecifier",children:"AccessSpecifier"})}),"\n"]}),"\n",(0,c.jsx)(i.h2,{id:"specifier-1",children:"Specifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity specifier: ",(0,c.jsx)(i.code,{children:"internal"}),", ",(0,c.jsx)(i.code,{children:"public"}),", ",(0,c.jsx)(i.code,{children:"private"}),", ",(0,c.jsx)(i.code,{children:"external"}),", ",(0,c.jsx)(i.code,{children:"pure"}),", ",(0,c.jsx)(i.code,{children:"view"}),", ",(0,c.jsx)(i.code,{children:"immutable"}),", ",(0,c.jsx)(i.code,{children:"virtual"}),"."]}),"\n",(0,c.jsx)(i.h3,{id:"methods",children:"Methods"}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#specifier-2",children:"Specifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass",children:"getAPrimaryQlClass()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getname",children:"getName()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#hasnamestring-name",children:"hasName(string name)"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"specifier-2",children:"Specifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"Specifier(){this instanceof Solidity::StateMutability or this instanceof Solidity::Visibility\n or this instanceof Solidity::Virtual\n}\n"})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "Specifier" }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"getname",children:"getName()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"string getName() { result = this.(Solidity::Token).getValue().toString() }\n"})}),"\n",(0,c.jsx)(i.p,{children:"Gets the name of this specifier."}),"\n",(0,c.jsx)(i.h3,{id:"hasnamestring-name",children:"hasName(string name)"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"predicate hasName(string name) { name = this.getName() }\n"})}),"\n",(0,c.jsxs)(i.p,{children:["Holds if the name of this specifier is ",(0,c.jsx)(i.code,{children:"name"}),"."]}),"\n",(0,c.jsx)(i.h2,{id:"functionspecifier",children:"FunctionSpecifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity function specifier: ",(0,c.jsx)(i.code,{children:"inline"}),", ",(0,c.jsx)(i.code,{children:"virtual"}),", or ",(0,c.jsx)(i.code,{children:"explicit"}),"."]}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#functionspecifier-1",children:"FunctionSpecifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"functionspecifier-1",children:"FunctionSpecifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'FunctionSpecifier() { this.hasName(["inline", "virtual", "explicit"]) }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "FunctionSpecifier" }\n'})}),"\n",(0,c.jsx)(i.h2,{id:"storageclassspecifier",children:"StorageClassSpecifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity storage class specifier: ",(0,c.jsx)(i.code,{children:"auto"}),", ",(0,c.jsx)(i.code,{children:"register"}),", ",(0,c.jsx)(i.code,{children:"static"}),", ",(0,c.jsx)(i.code,{children:"extern"}),", or ",(0,c.jsx)(i.code,{children:"mutable"}),"."]}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#storageclassspecifier-1",children:"StorageClassSpecifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass-2",children:"getAPrimaryQlClass()"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"storageclassspecifier-1",children:"StorageClassSpecifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'StorageClassSpecifier() { this.hasName(["auto", "register", "static", "extern", "mutable"]) }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "StorageClassSpecifier" }\n'})}),"\n",(0,c.jsx)(i.h2,{id:"accessspecifier",children:"AccessSpecifier"}),"\n",(0,c.jsxs)(i.p,{children:["A Solidity access specifier: ",(0,c.jsx)(i.code,{children:"public"}),", ",(0,c.jsx)(i.code,{children:"private"}),", ",(0,c.jsx)(i.code,{children:"internal"}),", ",(0,c.jsx)(i.code,{children:"external"}),"."]}),"\n",(0,c.jsxs)(i.ul,{children:["\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#accessspecifier-1",children:"AccessSpecifier()"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#accessindirectderivedaccessspecifier-baseaccess",children:"accessInDirectDerived(AccessSpecifier baseAccess)"})}),"\n",(0,c.jsx)(i.li,{children:(0,c.jsx)(i.a,{href:"#getaprimaryqlclass-3",children:"getAPrimaryQlClass()"})}),"\n"]}),"\n",(0,c.jsx)(i.h3,{id:"accessspecifier-1",children:"AccessSpecifier()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'AccessSpecifier() { this.hasName(["public", "private", "internal", "external"]) }\n'})}),"\n",(0,c.jsx)(i.h3,{id:"accessindirectderivedaccessspecifier-baseaccess",children:"accessInDirectDerived(AccessSpecifier baseAccess)"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'AccessSpecifier accessInDirectDerived(AccessSpecifier baseAccess) {\n this.getName() != "private" and\n (\n // Alphabetically, "private" < "protected" < "public". This disjunction\n // encodes that `result` is the minimum access of `this` and\n // `baseAccess`.\n baseAccess.getName() < this.getName() and result = baseAccess\n or\n baseAccess.getName() >= this.getName() and result = this\n )\n }\n'})}),"\n",(0,c.jsxs)(i.p,{children:["Gets the visibility of a field with access specifier ",(0,c.jsx)(i.code,{children:"this"})," if it is\ndirectly inherited with access specifier ",(0,c.jsx)(i.code,{children:"baseAccess"}),". For example:"]}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"class A { protected int f; };\nclass B : private A {};\n"})}),"\n",(0,c.jsxs)(i.p,{children:["In this example, ",(0,c.jsx)(i.code,{children:"this"})," is ",(0,c.jsx)(i.code,{children:"protected"}),", ",(0,c.jsx)(i.code,{children:"baseAccess"})," is ",(0,c.jsx)(i.code,{children:"private"}),", and\n",(0,c.jsx)(i.code,{children:"result"})," is ",(0,c.jsx)(i.code,{children:"private"})," because the visibility of field ",(0,c.jsx)(i.code,{children:"f"})," in class ",(0,c.jsx)(i.code,{children:"B"}),"\nis ",(0,c.jsx)(i.code,{children:"private"}),"."]}),"\n",(0,c.jsx)(i.p,{children:"This method encodes the rules of N4140 11.2/1, tabulated here:"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:"`this` | `baseAccess` | `result`\n(access in base) | (base class specifier) | (access in derived)\n----------------------------------------------------------\nprivate | private | N/A\nprivate | protected | N/A\nprivate | public | N/A\nprotected | private | private\nprotected | protected | protected\nprotected | public | protected\npublic | private | private\npublic | protected | protected\npublic | public | public\n"})}),"\n",(0,c.jsx)(i.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,c.jsx)(i.pre,{children:(0,c.jsx)(i.code,{children:'override string getAPrimaryQlClass() { result = "AccessSpecifier" }\n'})})]})}function o(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,c.jsx)(i,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},1503:(e,i,s)=>{s.d(i,{R:()=>l,x:()=>a});var c=s(758);const r={},n=c.createContext(r);function l(e){const i=c.useContext(n);return c.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),c.createElement(n.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/83a8eaf6.79eda485.js b/assets/js/83a8eaf6.79eda485.js new file mode 100644 index 0000000..082c1ea --- /dev/null +++ b/assets/js/83a8eaf6.79eda485.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[537],{6295:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var n=o(6070),t=o(1503);const l={},r="Control Flow Graph",c={id:"Classes/ControlFlowGraph",title:"Control Flow Graph",description:"In this module there is",source:"@site/docs/Classes/ControlFlowGraph.md",sourceDirName:"Classes",slug:"/Classes/ControlFlowGraph",permalink:"/CyScout/docs/Classes/ControlFlowGraph",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/ControlFlowGraph.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Call",permalink:"/CyScout/docs/Classes/Call"},next:{title:"Enclosing",permalink:"/CyScout/docs/Classes/Enclosing"}},i={},d=[{value:"Class ControlFlowNode",id:"class-controlflownode",level:2},{value:"Methods",id:"methods",level:3},{value:"getASuccessor()",id:"getasuccessor",level:3},{value:"getAPredecessor()",id:"getapredecessor",level:3},{value:"getControlFlowScope()",id:"getcontrolflowscope",level:3},{value:"getEnclosingStmt()",id:"getenclosingstmt",level:3},{value:"isCondition()",id:"iscondition",level:3},{value:"getATrueSuccessor()",id:"getatruesuccessor",level:3},{value:"getAFalseSuccessor()",id:"getafalsesuccessor",level:3},{value:"getBasicBlock()",id:"getbasicblock",level:3},{value:"Abstract class AdditionalControlFlowEdge",id:"abstract-class-additionalcontrolflowedge",level:2},{value:"Predicate successors_extended",id:"predicate-successors_extended",level:2}];function a(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"control-flow-graph",children:"Control Flow Graph"})}),"\n",(0,n.jsx)(s.p,{children:"In this module there is"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#class-controlflownode",children:"Class ControlFlowNode"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#abstract-class-additionalcontrolflowedge",children:"Abstract class AdditionalControlFlowEdge"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#predicate-successors_extended",children:"Predicate successors_extended"})}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"class-controlflownode",children:"Class ControlFlowNode"}),"\n",(0,n.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getasuccessor",children:"getASuccessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getapredecessor",children:"getAPredecessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getcontrolflowscope",children:"getControlFlowScope()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getenclosingstmt",children:"getEnclosingStmt()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#iscondition",children:"isCondition()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getatruesuccessor",children:"getATrueSuccessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getafalsesuccessor",children:"getAFalseSuccessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getbasicblock",children:"getBasicBlock()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getasuccessor",children:"getASuccessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getASuccessor() { successors_adapted(this, result) }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets a direct successor of this control-flow node, if any."}),"\n",(0,n.jsx)(s.h3,{id:"getapredecessor",children:"getAPredecessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getAPredecessor() { this = result.getASuccessor() }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets a direct predecessor of this control-flow node, if any."}),"\n",(0,n.jsx)(s.h3,{id:"getcontrolflowscope",children:"getControlFlowScope()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Solidity::FunctionDefinition getControlFlowScope() {\n none() // overridden in subclasses\n }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the function containing this control-flow node."}),"\n",(0,n.jsx)(s.h3,{id:"getenclosingstmt",children:"getEnclosingStmt()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:" Stmt getEnclosingStmt() {\n none() // overridden in subclasses\n }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the smallest statement containing this control-flow node."}),"\n",(0,n.jsx)(s.h3,{id:"iscondition",children:"isCondition()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isCondition() {\n exists(this.getATrueSuccessor()) or\n exists(this.getAFalseSuccessor())\n }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if this node is the top-level expression of a conditional statement, meaning that ",(0,n.jsx)(s.code,{children:"this.getATrueSuccessor()"})," or ",(0,n.jsx)(s.code,{children:"this.getAFalseSuccessor()"})," will have a result."]}),"\n",(0,n.jsx)(s.h3,{id:"getatruesuccessor",children:"getATrueSuccessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getATrueSuccessor() {\n qlCfgTrueSuccessor(this, result) and\n result = this.getASuccessor()\n }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,n.jsx)(s.code,{children:"(this, result)"})," may be taken when this expression is true."]}),"\n",(0,n.jsx)(s.h3,{id:"getafalsesuccessor",children:"getAFalseSuccessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getAFalseSuccessor() {\n qlCfgFalseSuccessor(this, result) and\n result = this.getASuccessor()\n }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,n.jsx)(s.code,{children:"(this, result)"})," may be when this expression is false."]}),"\n",(0,n.jsx)(s.h3,{id:"getbasicblock",children:"getBasicBlock()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"BasicBlock getBasicBlock() { result.getANode() = this }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Gets the ",(0,n.jsx)(s.code,{children:"BasicBlock"})," containing this control-flow node."]}),"\n",(0,n.jsx)(s.h2,{id:"abstract-class-additionalcontrolflowedge",children:"Abstract class AdditionalControlFlowEdge"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"getAnEdgeTarget()"}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"predicate-successors_extended",children:"Predicate successors_extended"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate successors_extended(ControlFlowNodeBase source, ControlFlowNodeBase target) {\n qlCfgSuccessor(source, target)\n or\n source.(AdditionalControlFlowEdge).getAnEdgeTarget() = target\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if there is a control-flow edge from ",(0,n.jsx)(s.code,{children:"source"})," to ",(0,n.jsx)(s.code,{children:"target"})," in either the extractor-generated control-flow graph or in a subclass of\n",(0,n.jsx)(s.code,{children:"AdditionalControlFlowEdge"}),". Use this relation instead of ",(0,n.jsx)(s.code,{children:"qlCFGSuccessor"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},1503:(e,s,o)=>{o.d(s,{R:()=>r,x:()=>c});var n=o(758);const t={},l=n.createContext(t);function r(e){const s=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),n.createElement(l.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/83a8eaf6.c8039eda.js b/assets/js/83a8eaf6.c8039eda.js deleted file mode 100644 index af2a17d..0000000 --- a/assets/js/83a8eaf6.c8039eda.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[537],{6295:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var n=o(6070),t=o(1503);const l={},r="Control Flow Graph",c={id:"Classes/ControlFlowGraph",title:"Control Flow Graph",description:"In this module there is",source:"@site/docs/Classes/ControlFlowGraph.md",sourceDirName:"Classes",slug:"/Classes/ControlFlowGraph",permalink:"/docs/Classes/ControlFlowGraph",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/ControlFlowGraph.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Call",permalink:"/docs/Classes/Call"},next:{title:"Enclosing",permalink:"/docs/Classes/Enclosing"}},i={},d=[{value:"Class ControlFlowNode",id:"class-controlflownode",level:2},{value:"Methods",id:"methods",level:3},{value:"getASuccessor()",id:"getasuccessor",level:3},{value:"getAPredecessor()",id:"getapredecessor",level:3},{value:"getControlFlowScope()",id:"getcontrolflowscope",level:3},{value:"getEnclosingStmt()",id:"getenclosingstmt",level:3},{value:"isCondition()",id:"iscondition",level:3},{value:"getATrueSuccessor()",id:"getatruesuccessor",level:3},{value:"getAFalseSuccessor()",id:"getafalsesuccessor",level:3},{value:"getBasicBlock()",id:"getbasicblock",level:3},{value:"Abstract class AdditionalControlFlowEdge",id:"abstract-class-additionalcontrolflowedge",level:2},{value:"Predicate successors_extended",id:"predicate-successors_extended",level:2}];function a(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"control-flow-graph",children:"Control Flow Graph"})}),"\n",(0,n.jsx)(s.p,{children:"In this module there is"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#class-controlflownode",children:"Class ControlFlowNode"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#abstract-class-additionalcontrolflowedge",children:"Abstract class AdditionalControlFlowEdge"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#predicate-successors_extended",children:"Predicate successors_extended"})}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"class-controlflownode",children:"Class ControlFlowNode"}),"\n",(0,n.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getasuccessor",children:"getASuccessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getapredecessor",children:"getAPredecessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getcontrolflowscope",children:"getControlFlowScope()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getenclosingstmt",children:"getEnclosingStmt()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#iscondition",children:"isCondition()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getatruesuccessor",children:"getATrueSuccessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getafalsesuccessor",children:"getAFalseSuccessor()"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"#getbasicblock",children:"getBasicBlock()"})}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"getasuccessor",children:"getASuccessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getASuccessor() { successors_adapted(this, result) }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets a direct successor of this control-flow node, if any."}),"\n",(0,n.jsx)(s.h3,{id:"getapredecessor",children:"getAPredecessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getAPredecessor() { this = result.getASuccessor() }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets a direct predecessor of this control-flow node, if any."}),"\n",(0,n.jsx)(s.h3,{id:"getcontrolflowscope",children:"getControlFlowScope()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"Solidity::FunctionDefinition getControlFlowScope() {\n none() // overridden in subclasses\n }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the function containing this control-flow node."}),"\n",(0,n.jsx)(s.h3,{id:"getenclosingstmt",children:"getEnclosingStmt()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:" Stmt getEnclosingStmt() {\n none() // overridden in subclasses\n }\n"})}),"\n",(0,n.jsx)(s.p,{children:"Gets the smallest statement containing this control-flow node."}),"\n",(0,n.jsx)(s.h3,{id:"iscondition",children:"isCondition()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate isCondition() {\n exists(this.getATrueSuccessor()) or\n exists(this.getAFalseSuccessor())\n }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if this node is the top-level expression of a conditional statement, meaning that ",(0,n.jsx)(s.code,{children:"this.getATrueSuccessor()"})," or ",(0,n.jsx)(s.code,{children:"this.getAFalseSuccessor()"})," will have a result."]}),"\n",(0,n.jsx)(s.h3,{id:"getatruesuccessor",children:"getATrueSuccessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getATrueSuccessor() {\n qlCfgTrueSuccessor(this, result) and\n result = this.getASuccessor()\n }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,n.jsx)(s.code,{children:"(this, result)"})," may be taken when this expression is true."]}),"\n",(0,n.jsx)(s.h3,{id:"getafalsesuccessor",children:"getAFalseSuccessor()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"ControlFlowNode getAFalseSuccessor() {\n qlCfgFalseSuccessor(this, result) and\n result = this.getASuccessor()\n }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,n.jsx)(s.code,{children:"(this, result)"})," may be when this expression is false."]}),"\n",(0,n.jsx)(s.h3,{id:"getbasicblock",children:"getBasicBlock()"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"BasicBlock getBasicBlock() { result.getANode() = this }\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Gets the ",(0,n.jsx)(s.code,{children:"BasicBlock"})," containing this control-flow node."]}),"\n",(0,n.jsx)(s.h2,{id:"abstract-class-additionalcontrolflowedge",children:"Abstract class AdditionalControlFlowEdge"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"getAnEdgeTarget()"}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"predicate-successors_extended",children:"Predicate successors_extended"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"predicate successors_extended(ControlFlowNodeBase source, ControlFlowNodeBase target) {\n qlCfgSuccessor(source, target)\n or\n source.(AdditionalControlFlowEdge).getAnEdgeTarget() = target\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Holds if there is a control-flow edge from ",(0,n.jsx)(s.code,{children:"source"})," to ",(0,n.jsx)(s.code,{children:"target"})," in either the extractor-generated control-flow graph or in a subclass of\n",(0,n.jsx)(s.code,{children:"AdditionalControlFlowEdge"}),". Use this relation instead of ",(0,n.jsx)(s.code,{children:"qlCFGSuccessor"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},1503:(e,s,o)=>{o.d(s,{R:()=>r,x:()=>c});var n=o(758);const t={},l=n.createContext(t);function r(e){const s=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),n.createElement(l.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/84e25d9a.2aba82da.js b/assets/js/84e25d9a.2aba82da.js deleted file mode 100644 index c368bf7..0000000 --- a/assets/js/84e25d9a.2aba82da.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[591],{8831:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>r});var c=n(6070),i=n(1503);const l={},o="SubBasicBlock",t={id:"Classes/SubBasicBlock",title:"SubBasicBlock",description:"Provides the SubBasicBlock class, used for partitioning basic blocks in smaller pieces.",source:"@site/docs/Classes/SubBasicBlock.md",sourceDirName:"Classes",slug:"/Classes/SubBasicBlock",permalink:"/docs/Classes/SubBasicBlock",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/SubBasicBlock.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Specifier",permalink:"/docs/Classes/Specifier"},next:{title:"Variable",permalink:"/docs/Classes/Variable"}},d={},r=[{value:"Classes",id:"classes",level:2},{value:"SubBasicBlockCutNode",id:"subbasicblockcutnode",level:2},{value:"Methods",id:"methods",level:3},{value:"SubBasicBlockCutNode()",id:"subbasicblockcutnode-1",level:3},{value:"SubBasicBlock",id:"subbasicblock-1",level:2},{value:"Methods",id:"methods-1",level:3},{value:"SubBasicBlock()",id:"subbasicblock-2",level:3},{value:"getBasicBlock()",id:"getbasicblock",level:3},{value:"firstInBB()",id:"firstinbb",level:3},{value:"lastInBB()",id:"lastinbb",level:3},{value:"getRankInBasicBlock(BasicBlock bb)",id:"getrankinbasicblockbasicblock-bb",level:3},{value:"getIndexInBasicBlock(BasicBlock bb)",id:"getindexinbasicblockbasicblock-bb",level:3},{value:"getASuccessor()",id:"getasuccessor",level:3},{value:"getNode(int index)",id:"getnodeint-index",level:3},{value:"outerToInnerIndex(BasicBlock bb, int indexInBB)",id:"outertoinnerindexbasicblock-bb-int-indexinbb",level:3},{value:"getANode()",id:"getanode",level:3},{value:"contains(ControlFlowNode node)",id:"containscontrolflownode-node",level:3},{value:"getAPredecessor()",id:"getapredecessor",level:3},{value:"getATrueSuccessor()",id:"getatruesuccessor",level:3},{value:"getAFalseSuccessor()",id:"getafalsesuccessor",level:3},{value:"getNumberOfNodes()",id:"getnumberofnodes",level:3},{value:"getEnd()",id:"getend",level:3},{value:"getStart()",id:"getstart",level:3},{value:"getEnclosingFunction()",id:"getenclosingfunction",level:3},{value:"Function",id:"function",level:2},{value:"countSubBasicBlocksInBasicBlock(BasicBlock bb)",id:"countsubbasicblocksinbasicblockbasicblock-bb",level:3}];function a(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"subbasicblock",children:"SubBasicBlock"})}),"\n",(0,c.jsxs)(s.p,{children:["Provides the ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," class, used for partitioning basic blocks in smaller pieces."]}),"\n",(0,c.jsx)(s.h2,{id:"classes",children:"Classes"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblockcutnode",children:"SubBasicBlockCutNode"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblock",children:"SubBasicBlock"})}),"\n"]}),"\n",(0,c.jsx)(s.h2,{id:"subbasicblockcutnode",children:"SubBasicBlockCutNode"}),"\n",(0,c.jsxs)(s.p,{children:["An abstract class that directs where in the control-flow graph a new ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," must start. If a ",(0,c.jsx)(s.code,{children:"ControlFlowNode"})," is an instance of this class, that node is guaranteed to be the first node in a ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsxs)(s.p,{children:["If multiple libraries use the ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," library, basic blocks may be split in more places than either library expects, but nothing should break as a direct result of that."]}),"\n",(0,c.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblock-1",children:"SubBasicBlockCutNode()"})}),"\n"]}),"\n",(0,c.jsx)(s.h3,{id:"subbasicblockcutnode-1",children:"SubBasicBlockCutNode()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlockCutNode() {\n exists(this.getBasicBlock())\n }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Some control-flow nodes are not in any basic block. This includes\n",(0,c.jsx)(s.code,{children:"Conversion"}),"s, expressions that are evaluated at compile time, default arguments, and ",(0,c.jsx)(s.code,{children:"Function"}),"s without implementation."]}),"\n",(0,c.jsx)(s.h2,{id:"subbasicblock-1",children:"SubBasicBlock"}),"\n",(0,c.jsxs)(s.p,{children:["A block that can be smaller than or equal to a ",(0,c.jsx)(s.code,{children:"BasicBlock"}),". Use this class when ",(0,c.jsx)(s.code,{children:"ControlFlowNode"})," is too fine-grained and ",(0,c.jsx)(s.code,{children:"BasicBlock"})," too\ncoarse-grained. Their successor graph is like that of basic blocks, except that the blocks are split up with an extra edge right before any instance of the abstract class ",(0,c.jsx)(s.code,{children:"SubBasicBlockCutNode"}),". Users of this library must therefore extend ",(0,c.jsx)(s.code,{children:"SubBasicBlockCutNode"})," to direct where basic blocks will be\nsplit up."]}),"\n",(0,c.jsx)(s.h3,{id:"methods-1",children:"Methods"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblock-2",children:"SubBasicBlock()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getbasicblock",children:"getBasicBlock()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#firstinbb",children:"firstInBB()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#lastinbb",children:"lastInBB()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getrankinbasicblockbasicblock-bb",children:"getRankInBasicBlock(BasicBlock bb)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getindexinbasicblockbasicblock-bb",children:"getIndexInBasicBlock(BasicBlock bb)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getasuccessor",children:"getASuccessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getnodeint-index",children:"getNode(int index)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#outertoinnerindexbasicblock-bb-int-indexinbb",children:"outerToInnerIndex(BasicBlock bb, int indexInBB)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getanode",children:"getANode()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#containscontrolflownode-node",children:"contains(ControlFlowNode node)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getapredecessor",children:"getAPredecessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getatruesuccessor",children:"getATrueSuccessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getafalsesuccessor",children:"getAFalseSuccessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getnumberofnodes",children:"getNumberOfNodes()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getend",children:"getEnd()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getstart",children:"getStart()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getenclosingfunction",children:"getEnclosingFunction()"})}),"\n"]}),"\n",(0,c.jsx)(s.h3,{id:"subbasicblock-2",children:"SubBasicBlock()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock() {\n this instanceof BasicBlock\n or\n this instanceof SubBasicBlockCutNode\n}\n"})}),"\n",(0,c.jsx)(s.h3,{id:"getbasicblock",children:"getBasicBlock()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"BasicBlock getBasicBlock() { result = this.(ControlFlowNode).getBasicBlock()}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the basic block in which this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," is contained."]}),"\n",(0,c.jsx)(s.h3,{id:"firstinbb",children:"firstInBB()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"predicate firstInBB() { this.getRankInBasicBlock(_) = 1 }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Holds if this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," comes first in its basic block. This is the only condition under which a ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," may have multiple\npredecessors."]}),"\n",(0,c.jsx)(s.h3,{id:"lastinbb",children:"lastInBB()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"predicate lastInBB() {\n exists(BasicBlock bb | this.getRankInBasicBlock(bb) = countSubBasicBlocksInBasicBlock(bb))\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Holds if this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," comes last in its basic block. This is the only condition under which a ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," may have multiple successors."]}),"\n",(0,c.jsx)(s.h3,{id:"getrankinbasicblockbasicblock-bb",children:"getRankInBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"int getRankInBasicBlock(BasicBlock bb) {\n exists(int thisIndexInBB |\n thisIndexInBB = this.getIndexInBasicBlock(bb) and\n thisIndexInBB = rank[result](int i | i = any(SubBasicBlock n).getIndexInBasicBlock(bb))\n )\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the (1-based) rank of this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," among the other ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s in its containing basic block ",(0,c.jsx)(s.code,{children:"bb"}),", where ",(0,c.jsx)(s.code,{children:"bb"})," is equal to ",(0,c.jsx)(s.code,{children:"getBasicBlock()"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getindexinbasicblockbasicblock-bb",children:"getIndexInBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }\n"})}),"\n",(0,c.jsx)(s.h3,{id:"getasuccessor",children:"getASuccessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getASuccessor() {\n this.lastInBB() and\n result = this.getBasicBlock().getASuccessor()\n or\n exists(BasicBlock bb | result.getRankInBasicBlock(bb) = this.getRankInBasicBlock(bb) + 1)\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a successor in the control-flow graph of ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s."]}),"\n",(0,c.jsx)(s.h3,{id:"getnodeint-index",children:"getNode(int index)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getNode(int index) {\n exists(BasicBlock bb |\n exists(int outerIndex |\n result = bb.getNode(outerIndex) and\n index = this.outerToInnerIndex(bb, outerIndex)\n )\n )\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the ",(0,c.jsx)(s.code,{children:"index"}),"th control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),". Indexes start from 0, and the node at index 0 always exists and compares equal to ",(0,c.jsx)(s.code,{children:"this"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"outertoinnerindexbasicblock-bb-int-indexinbb",children:"outerToInnerIndex(BasicBlock bb, int indexInBB)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"private int outerToInnerIndex(BasicBlock bb, int indexInBB) {\n indexInBB = result + this.getIndexInBasicBlock(bb) and\n result = [0 .. this.getNumberOfNodes() - 1]\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the index of the node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," that has ",(0,c.jsx)(s.code,{children:"indexInBB"})," in ",(0,c.jsx)(s.code,{children:"bb"}),", where ",(0,c.jsx)(s.code,{children:"bb"})," is equal to ",(0,c.jsx)(s.code,{children:"getBasicBlock()"}),"."]}),"\n",(0,c.jsxs)(s.p,{children:["This predicate is factored out of ",(0,c.jsx)(s.code,{children:"getNode"})," to ensure a good join order.\nIt's sensitive to bad magic, so it has ",(0,c.jsx)(s.code,{children:"pragma[nomagic]"})," on it. For example, it can get very slow if ",(0,c.jsx)(s.code,{children:"getNode"})," is pragma[nomagic], which could mean it might get very slow if ",(0,c.jsx)(s.code,{children:"getNode"})," is used in the wrong context."]}),"\n",(0,c.jsx)(s.h3,{id:"getanode",children:"getANode()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getANode() { result = this.getNode(_) }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"containscontrolflownode-node",children:"contains(ControlFlowNode node)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"predicate contains(ControlFlowNode node) { node = this.getANode() }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Holds if ",(0,c.jsx)(s.code,{children:"this"})," contains ",(0,c.jsx)(s.code,{children:"node"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getapredecessor",children:"getAPredecessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getAPredecessor() { result.getASuccessor() = this }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a predecessor in the control-flow graph of ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s."]}),"\n",(0,c.jsx)(s.h3,{id:"getatruesuccessor",children:"getATrueSuccessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getATrueSuccessor() {\n this.lastInBB() and\n result = this.getBasicBlock().getATrueSuccessor()\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,c.jsx)(s.code,{children:"(this, result)"})," may be taken when the final node of this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," is a conditional expression and evaluates to true."]}),"\n",(0,c.jsx)(s.h3,{id:"getafalsesuccessor",children:"getAFalseSuccessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getAFalseSuccessor() {\n this.lastInBB() and\n result = this.getBasicBlock().getAFalseSuccessor()\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,c.jsx)(s.code,{children:"(this, result)"})," may be taken when the final node of this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," is a conditional expression and evaluates to false."]}),"\n",(0,c.jsx)(s.h3,{id:"getnumberofnodes",children:"getNumberOfNodes()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"int getNumberOfNodes() {\n exists(BasicBlock bb |\n if this.lastInBB()\n then result = bb.length() - this.getIndexInBasicBlock(bb)\n else result = this.getASuccessor().getIndexInBasicBlock(bb) - this.getIndexInBasicBlock(bb)\n )\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the number of control-flow nodes in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),". There is always at least one."]}),"\n",(0,c.jsx)(s.h3,{id:"getend",children:"getEnd()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getEnd() { result = this.getNode(this.getNumberOfNodes() - 1) }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the last control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getstart",children:"getStart()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getStart() { result = this }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the first control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getenclosingfunction",children:"getEnclosingFunction()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"Function getEnclosingFunction() { result = this.getStart().getControlFlowScope() }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the function that contains this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"function",children:"Function"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#countsubbasicblocksinbasicblockbasicblock-bb",children:"countSubBasicBlocksInBasicBlock(BasicBlock bb)"})}),"\n"]}),"\n",(0,c.jsx)(s.h3,{id:"countsubbasicblocksinbasicblockbasicblock-bb",children:"countSubBasicBlocksInBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"private int countSubBasicBlocksInBasicBlock(BasicBlock bb) {\n result = strictcount(SubBasicBlock sbb | sbb.getBasicBlock() = bb)\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the number of ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s in the given basic block."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(a,{...e})}):a(e)}},1503:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>t});var c=n(758);const i={},l=c.createContext(i);function o(e){const s=c.useContext(l);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),c.createElement(l.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/84e25d9a.a45a336a.js b/assets/js/84e25d9a.a45a336a.js new file mode 100644 index 0000000..3a787e1 --- /dev/null +++ b/assets/js/84e25d9a.a45a336a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[591],{8831:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>r});var c=n(6070),i=n(1503);const l={},o="SubBasicBlock",t={id:"Classes/SubBasicBlock",title:"SubBasicBlock",description:"Provides the SubBasicBlock class, used for partitioning basic blocks in smaller pieces.",source:"@site/docs/Classes/SubBasicBlock.md",sourceDirName:"Classes",slug:"/Classes/SubBasicBlock",permalink:"/CyScout/docs/Classes/SubBasicBlock",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/SubBasicBlock.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Specifier",permalink:"/CyScout/docs/Classes/Specifier"},next:{title:"Variable",permalink:"/CyScout/docs/Classes/Variable"}},d={},r=[{value:"Classes",id:"classes",level:2},{value:"SubBasicBlockCutNode",id:"subbasicblockcutnode",level:2},{value:"Methods",id:"methods",level:3},{value:"SubBasicBlockCutNode()",id:"subbasicblockcutnode-1",level:3},{value:"SubBasicBlock",id:"subbasicblock-1",level:2},{value:"Methods",id:"methods-1",level:3},{value:"SubBasicBlock()",id:"subbasicblock-2",level:3},{value:"getBasicBlock()",id:"getbasicblock",level:3},{value:"firstInBB()",id:"firstinbb",level:3},{value:"lastInBB()",id:"lastinbb",level:3},{value:"getRankInBasicBlock(BasicBlock bb)",id:"getrankinbasicblockbasicblock-bb",level:3},{value:"getIndexInBasicBlock(BasicBlock bb)",id:"getindexinbasicblockbasicblock-bb",level:3},{value:"getASuccessor()",id:"getasuccessor",level:3},{value:"getNode(int index)",id:"getnodeint-index",level:3},{value:"outerToInnerIndex(BasicBlock bb, int indexInBB)",id:"outertoinnerindexbasicblock-bb-int-indexinbb",level:3},{value:"getANode()",id:"getanode",level:3},{value:"contains(ControlFlowNode node)",id:"containscontrolflownode-node",level:3},{value:"getAPredecessor()",id:"getapredecessor",level:3},{value:"getATrueSuccessor()",id:"getatruesuccessor",level:3},{value:"getAFalseSuccessor()",id:"getafalsesuccessor",level:3},{value:"getNumberOfNodes()",id:"getnumberofnodes",level:3},{value:"getEnd()",id:"getend",level:3},{value:"getStart()",id:"getstart",level:3},{value:"getEnclosingFunction()",id:"getenclosingfunction",level:3},{value:"Function",id:"function",level:2},{value:"countSubBasicBlocksInBasicBlock(BasicBlock bb)",id:"countsubbasicblocksinbasicblockbasicblock-bb",level:3}];function a(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"subbasicblock",children:"SubBasicBlock"})}),"\n",(0,c.jsxs)(s.p,{children:["Provides the ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," class, used for partitioning basic blocks in smaller pieces."]}),"\n",(0,c.jsx)(s.h2,{id:"classes",children:"Classes"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblockcutnode",children:"SubBasicBlockCutNode"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblock",children:"SubBasicBlock"})}),"\n"]}),"\n",(0,c.jsx)(s.h2,{id:"subbasicblockcutnode",children:"SubBasicBlockCutNode"}),"\n",(0,c.jsxs)(s.p,{children:["An abstract class that directs where in the control-flow graph a new ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," must start. If a ",(0,c.jsx)(s.code,{children:"ControlFlowNode"})," is an instance of this class, that node is guaranteed to be the first node in a ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsxs)(s.p,{children:["If multiple libraries use the ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," library, basic blocks may be split in more places than either library expects, but nothing should break as a direct result of that."]}),"\n",(0,c.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblock-1",children:"SubBasicBlockCutNode()"})}),"\n"]}),"\n",(0,c.jsx)(s.h3,{id:"subbasicblockcutnode-1",children:"SubBasicBlockCutNode()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlockCutNode() {\n exists(this.getBasicBlock())\n }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Some control-flow nodes are not in any basic block. This includes\n",(0,c.jsx)(s.code,{children:"Conversion"}),"s, expressions that are evaluated at compile time, default arguments, and ",(0,c.jsx)(s.code,{children:"Function"}),"s without implementation."]}),"\n",(0,c.jsx)(s.h2,{id:"subbasicblock-1",children:"SubBasicBlock"}),"\n",(0,c.jsxs)(s.p,{children:["A block that can be smaller than or equal to a ",(0,c.jsx)(s.code,{children:"BasicBlock"}),". Use this class when ",(0,c.jsx)(s.code,{children:"ControlFlowNode"})," is too fine-grained and ",(0,c.jsx)(s.code,{children:"BasicBlock"})," too\ncoarse-grained. Their successor graph is like that of basic blocks, except that the blocks are split up with an extra edge right before any instance of the abstract class ",(0,c.jsx)(s.code,{children:"SubBasicBlockCutNode"}),". Users of this library must therefore extend ",(0,c.jsx)(s.code,{children:"SubBasicBlockCutNode"})," to direct where basic blocks will be\nsplit up."]}),"\n",(0,c.jsx)(s.h3,{id:"methods-1",children:"Methods"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#subbasicblock-2",children:"SubBasicBlock()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getbasicblock",children:"getBasicBlock()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#firstinbb",children:"firstInBB()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#lastinbb",children:"lastInBB()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getrankinbasicblockbasicblock-bb",children:"getRankInBasicBlock(BasicBlock bb)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getindexinbasicblockbasicblock-bb",children:"getIndexInBasicBlock(BasicBlock bb)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getasuccessor",children:"getASuccessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getnodeint-index",children:"getNode(int index)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#outertoinnerindexbasicblock-bb-int-indexinbb",children:"outerToInnerIndex(BasicBlock bb, int indexInBB)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getanode",children:"getANode()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#containscontrolflownode-node",children:"contains(ControlFlowNode node)"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getapredecessor",children:"getAPredecessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getatruesuccessor",children:"getATrueSuccessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getafalsesuccessor",children:"getAFalseSuccessor()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getnumberofnodes",children:"getNumberOfNodes()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getend",children:"getEnd()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getstart",children:"getStart()"})}),"\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#getenclosingfunction",children:"getEnclosingFunction()"})}),"\n"]}),"\n",(0,c.jsx)(s.h3,{id:"subbasicblock-2",children:"SubBasicBlock()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock() {\n this instanceof BasicBlock\n or\n this instanceof SubBasicBlockCutNode\n}\n"})}),"\n",(0,c.jsx)(s.h3,{id:"getbasicblock",children:"getBasicBlock()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"BasicBlock getBasicBlock() { result = this.(ControlFlowNode).getBasicBlock()}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the basic block in which this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," is contained."]}),"\n",(0,c.jsx)(s.h3,{id:"firstinbb",children:"firstInBB()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"predicate firstInBB() { this.getRankInBasicBlock(_) = 1 }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Holds if this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," comes first in its basic block. This is the only condition under which a ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," may have multiple\npredecessors."]}),"\n",(0,c.jsx)(s.h3,{id:"lastinbb",children:"lastInBB()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"predicate lastInBB() {\n exists(BasicBlock bb | this.getRankInBasicBlock(bb) = countSubBasicBlocksInBasicBlock(bb))\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Holds if this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," comes last in its basic block. This is the only condition under which a ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," may have multiple successors."]}),"\n",(0,c.jsx)(s.h3,{id:"getrankinbasicblockbasicblock-bb",children:"getRankInBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"int getRankInBasicBlock(BasicBlock bb) {\n exists(int thisIndexInBB |\n thisIndexInBB = this.getIndexInBasicBlock(bb) and\n thisIndexInBB = rank[result](int i | i = any(SubBasicBlock n).getIndexInBasicBlock(bb))\n )\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the (1-based) rank of this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," among the other ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s in its containing basic block ",(0,c.jsx)(s.code,{children:"bb"}),", where ",(0,c.jsx)(s.code,{children:"bb"})," is equal to ",(0,c.jsx)(s.code,{children:"getBasicBlock()"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getindexinbasicblockbasicblock-bb",children:"getIndexInBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }\n"})}),"\n",(0,c.jsx)(s.h3,{id:"getasuccessor",children:"getASuccessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getASuccessor() {\n this.lastInBB() and\n result = this.getBasicBlock().getASuccessor()\n or\n exists(BasicBlock bb | result.getRankInBasicBlock(bb) = this.getRankInBasicBlock(bb) + 1)\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a successor in the control-flow graph of ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s."]}),"\n",(0,c.jsx)(s.h3,{id:"getnodeint-index",children:"getNode(int index)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getNode(int index) {\n exists(BasicBlock bb |\n exists(int outerIndex |\n result = bb.getNode(outerIndex) and\n index = this.outerToInnerIndex(bb, outerIndex)\n )\n )\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the ",(0,c.jsx)(s.code,{children:"index"}),"th control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),". Indexes start from 0, and the node at index 0 always exists and compares equal to ",(0,c.jsx)(s.code,{children:"this"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"outertoinnerindexbasicblock-bb-int-indexinbb",children:"outerToInnerIndex(BasicBlock bb, int indexInBB)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"private int outerToInnerIndex(BasicBlock bb, int indexInBB) {\n indexInBB = result + this.getIndexInBasicBlock(bb) and\n result = [0 .. this.getNumberOfNodes() - 1]\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the index of the node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," that has ",(0,c.jsx)(s.code,{children:"indexInBB"})," in ",(0,c.jsx)(s.code,{children:"bb"}),", where ",(0,c.jsx)(s.code,{children:"bb"})," is equal to ",(0,c.jsx)(s.code,{children:"getBasicBlock()"}),"."]}),"\n",(0,c.jsxs)(s.p,{children:["This predicate is factored out of ",(0,c.jsx)(s.code,{children:"getNode"})," to ensure a good join order.\nIt's sensitive to bad magic, so it has ",(0,c.jsx)(s.code,{children:"pragma[nomagic]"})," on it. For example, it can get very slow if ",(0,c.jsx)(s.code,{children:"getNode"})," is pragma[nomagic], which could mean it might get very slow if ",(0,c.jsx)(s.code,{children:"getNode"})," is used in the wrong context."]}),"\n",(0,c.jsx)(s.h3,{id:"getanode",children:"getANode()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getANode() { result = this.getNode(_) }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"containscontrolflownode-node",children:"contains(ControlFlowNode node)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"predicate contains(ControlFlowNode node) { node = this.getANode() }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Holds if ",(0,c.jsx)(s.code,{children:"this"})," contains ",(0,c.jsx)(s.code,{children:"node"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getapredecessor",children:"getAPredecessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getAPredecessor() { result.getASuccessor() = this }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a predecessor in the control-flow graph of ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s."]}),"\n",(0,c.jsx)(s.h3,{id:"getatruesuccessor",children:"getATrueSuccessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getATrueSuccessor() {\n this.lastInBB() and\n result = this.getBasicBlock().getATrueSuccessor()\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,c.jsx)(s.code,{children:"(this, result)"})," may be taken when the final node of this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," is a conditional expression and evaluates to true."]}),"\n",(0,c.jsx)(s.h3,{id:"getafalsesuccessor",children:"getAFalseSuccessor()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"SubBasicBlock getAFalseSuccessor() {\n this.lastInBB() and\n result = this.getBasicBlock().getAFalseSuccessor()\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets a node such that the control-flow edge ",(0,c.jsx)(s.code,{children:"(this, result)"})," may be taken when the final node of this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"})," is a conditional expression and evaluates to false."]}),"\n",(0,c.jsx)(s.h3,{id:"getnumberofnodes",children:"getNumberOfNodes()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"int getNumberOfNodes() {\n exists(BasicBlock bb |\n if this.lastInBB()\n then result = bb.length() - this.getIndexInBasicBlock(bb)\n else result = this.getASuccessor().getIndexInBasicBlock(bb) - this.getIndexInBasicBlock(bb)\n )\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the number of control-flow nodes in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),". There is always at least one."]}),"\n",(0,c.jsx)(s.h3,{id:"getend",children:"getEnd()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getEnd() { result = this.getNode(this.getNumberOfNodes() - 1) }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the last control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getstart",children:"getStart()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"ControlFlowNode getStart() { result = this }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the first control-flow node in this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h3,{id:"getenclosingfunction",children:"getEnclosingFunction()"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"Function getEnclosingFunction() { result = this.getStart().getControlFlowScope() }\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the function that contains this ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"function",children:"Function"}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:(0,c.jsx)(s.a,{href:"#countsubbasicblocksinbasicblockbasicblock-bb",children:"countSubBasicBlocksInBasicBlock(BasicBlock bb)"})}),"\n"]}),"\n",(0,c.jsx)(s.h3,{id:"countsubbasicblocksinbasicblockbasicblock-bb",children:"countSubBasicBlocksInBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsx)(s.pre,{children:(0,c.jsx)(s.code,{children:"private int countSubBasicBlocksInBasicBlock(BasicBlock bb) {\n result = strictcount(SubBasicBlock sbb | sbb.getBasicBlock() = bb)\n}\n"})}),"\n",(0,c.jsxs)(s.p,{children:["Gets the number of ",(0,c.jsx)(s.code,{children:"SubBasicBlock"}),"s in the given basic block."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(a,{...e})}):a(e)}},1503:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>t});var c=n(758);const i={},l=c.createContext(i);function o(e){const s=c.useContext(l);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),c.createElement(l.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8c56a58b.e2fb2478.js b/assets/js/8c56a58b.e2fb2478.js new file mode 100644 index 0000000..de6c693 --- /dev/null +++ b/assets/js/8c56a58b.e2fb2478.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[613],{3312:(e,t,c)=>{c.r(t),c.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>a,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var n=c(6070),r=c(1503);const s={},o="Unrpotected self destruct",i={id:"Detectors/unprotected-self-destruct",title:"Unrpotected self destruct",description:"Description",source:"@site/docs/Detectors/unprotected-self-destruct.md",sourceDirName:"Detectors",slug:"/Detectors/unprotected-self-destruct",permalink:"/CyScout/docs/Detectors/unprotected-self-destruct",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/unprotected-self-destruct.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Unchecked Send",permalink:"/CyScout/docs/Detectors/unchecked-send"},next:{title:"CyScout",permalink:"/CyScout/docs/README/"}},d={},l=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function u(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"unrpotected-self-destruct",children:"Unrpotected self destruct"})}),"\n",(0,n.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(t.p,{children:["Based on Slither's ",(0,n.jsx)(t.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#suicidal",children:"suicidal detector"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Unprotected call to a function executing selfdestruct/suicide."}),"\n",(0,n.jsx)(t.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"contract Suicidal{\n function kill() public{\n selfdestruct(msg.sender);\n }\n}\n"})}),"\n",(0,n.jsx)(t.p,{children:"Bob calls kill and destructs the contract."}),"\n",(0,n.jsx)(t.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,n.jsx)(t.p,{children:"Protect access to all sensitive functions."})]})}function a(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},1503:(e,t,c)=>{c.d(t,{R:()=>o,x:()=>i});var n=c(758);const r={},s=n.createContext(r);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8c56a58b.f7119cdb.js b/assets/js/8c56a58b.f7119cdb.js deleted file mode 100644 index caeb2c6..0000000 --- a/assets/js/8c56a58b.f7119cdb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[613],{3312:(e,t,c)=>{c.r(t),c.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var n=c(6070),r=c(1503);const s={},o="Unrpotected self destruct",i={id:"Detectors/unprotected-self-destruct",title:"Unrpotected self destruct",description:"Description",source:"@site/docs/Detectors/unprotected-self-destruct.md",sourceDirName:"Detectors",slug:"/Detectors/unprotected-self-destruct",permalink:"/docs/Detectors/unprotected-self-destruct",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/unprotected-self-destruct.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Unchecked Send",permalink:"/docs/Detectors/unchecked-send"},next:{title:"CyScout",permalink:"/docs/README/"}},d={},l=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"unrpotected-self-destruct",children:"Unrpotected self destruct"})}),"\n",(0,n.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(t.p,{children:["Based on Slither's ",(0,n.jsx)(t.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#suicidal",children:"suicidal detector"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Unprotected call to a function executing selfdestruct/suicide."}),"\n",(0,n.jsx)(t.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"contract Suicidal{\n function kill() public{\n selfdestruct(msg.sender);\n }\n}\n"})}),"\n",(0,n.jsx)(t.p,{children:"Bob calls kill and destructs the contract."}),"\n",(0,n.jsx)(t.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,n.jsx)(t.p,{children:"Protect access to all sensitive functions."})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},1503:(e,t,c)=>{c.d(t,{R:()=>o,x:()=>i});var n=c(758);const r={},s=n.createContext(r);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/94ad6ac6.19dc302c.js b/assets/js/94ad6ac6.19dc302c.js deleted file mode 100644 index c53b589..0000000 --- a/assets/js/94ad6ac6.19dc302c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[487],{4016:(e,s,a)=>{a.r(s),a.d(s,{assets:()=>d,contentTitle:()=>r,default:()=>x,frontMatter:()=>c,metadata:()=>n,toc:()=>t});var l=a(6070),i=a(1503);const c={},r="Variable",n={id:"Classes/Variable",title:"Variable",description:"Classes",source:"@site/docs/Classes/Variable.md",sourceDirName:"Classes",slug:"/Classes/Variable",permalink:"/docs/Classes/Variable",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Variable.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"SubBasicBlock",permalink:"/docs/Classes/SubBasicBlock"},next:{title:"Index",permalink:"/docs/Classes/classesIndex"}},d={},t=[{value:"Classes",id:"classes",level:2},{value:"Variable",id:"variable-1",level:2},{value:"getName()",id:"getname",level:3},{value:"hasName()",id:"hasname",level:3},{value:"toString()",id:"tostring",level:3},{value:"getLocation()",id:"getlocation",level:3},{value:"getDeclaringScope()",id:"getdeclaringscope",level:3},{value:"getAnAccess()",id:"getanaccess",level:3},{value:"LocalVariable",id:"localvariable",level:2},{value:"Methods",id:"methods",level:3},{value:"getAnAccess()",id:"getanaccess-1",level:3},{value:"getDefiningAccess()",id:"getdefiningaccess",level:3},{value:"isCaptured()",id:"iscaptured",level:3},{value:"GlobalVariable",id:"globalvariable",level:2},{value:"getAnAccess()",id:"getanaccess-2",level:3},{value:"InstanceVariable",id:"instancevariable",level:2},{value:"isClassInstanceVariable()",id:"isclassinstancevariable",level:3},{value:"getAnAccess()",id:"getanaccess-3",level:3},{value:"ClassVariable",id:"classvariable",level:2},{value:"getAnAccess()",id:"getanaccess-4",level:3},{value:"SelfVariable",id:"selfvariable",level:2},{value:"VariableAccess",id:"variableaccess",level:2},{value:"getVariable()",id:"getvariable",level:3},{value:"isExplicitWrite(AstNode assignment)",id:"isexplicitwriteastnode-assignment",level:3},{value:"isImplicitWrite()",id:"isimplicitwrite",level:3},{value:"VariableWriteAccess",id:"variablewriteaccess",level:2},{value:"VariableReadAccess",id:"variablereadaccess",level:2},{value:"LocalVariableAccess",id:"localvariableaccess",level:2},{value:"getAPrimaryQlClasses()",id:"getaprimaryqlclasses",level:3},{value:"isCapturedAccess()",id:"iscapturedaccess",level:3},{value:"LocalVariableWriteAccess",id:"localvariablewriteaccess",level:2},{value:"LocalVariableReadAccess",id:"localvariablereadaccess",level:2},{value:"GlobalVariableAccess",id:"globalvariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"GlobalVariableWriteAccess",id:"globalvariablewriteaccess",level:2},{value:"GlobalVariableReadAccess",id:"globalvariablereadaccess",level:2},{value:"InstanceVariableAccess",id:"instancevariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"getReceiver()",id:"getreceiver",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred",level:3},{value:"InstanceVariableWriteAccess",id:"instancevariablewriteaccess",level:2},{value:"InstanceVariableReadAccess",id:"instancevariablereadaccess",level:2},{value:"ClassVariableAccess",id:"classvariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"ClassVariableWriteAccess",id:"classvariablewriteaccess",level:2},{value:"ClassVariableReadAccess",id:"classvariablereadaccess",level:2},{value:"SelfVariableAccess",id:"selfvariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3},{value:"SelfVariableReadAccess",id:"selfvariablereadaccess",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.header,{children:(0,l.jsx)(s.h1,{id:"variable",children:"Variable"})}),"\n",(0,l.jsx)(s.h2,{id:"classes",children:"Classes"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variable-1",children:"Variable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariable",children:"LocalVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariable",children:"GlobalVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariable",children:"InstanceVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariable",children:"ClassVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#selfvariable",children:"SelfVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variableaccess",children:"VariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variablewriteaccess",children:"VariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variablereadaccess",children:"VariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariableaccess",children:"LocalVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariablewriteaccess",children:"LocalVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariablereadaccess",children:"LocalVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariableaccess",children:"GlobalVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariablewriteaccess",children:"GlobalVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariablewriteaccess",children:"GlobalVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariableaccess",children:"InstanceVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariablewriteaccess",children:"InstanceVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariablereadaccess",children:"InstanceVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariableaccess",children:"ClassVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariablewriteaccess",children:"ClassVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariablereadaccess",children:"ClassVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#selfvariableaccess",children:"SelfVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#selfvariablereadaccess",children:"SelfVariableReadAccess"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"variable-1",children:"Variable"}),"\n",(0,l.jsx)(s.p,{children:"A variable declared in a scope."}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getname",children:"getName()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#hasname",children:"hasName()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#tostring",children:"toString()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getlocation",children:"getLocation()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getdeclaringscope",children:"getDeclaringScope()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess",children:"getAnAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getname",children:"getName()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final string getName() { result = super.getNameImpl() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the name of this variable."}),"\n",(0,l.jsx)(s.h3,{id:"hasname",children:"hasName()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate hasName(string name) { this.getName() = name }\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Holds if the name of this variable is a ",(0,l.jsx)(s.code,{children:"name"}),"."]}),"\n",(0,l.jsx)(s.h3,{id:"tostring",children:"toString()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final string toString() { result = this.getName() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets a textual representation of this variable."}),"\n",(0,l.jsx)(s.h3,{id:"getlocation",children:"getLocation()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final Location getLocation() { result = super.getLocationImpl() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the location of this variable."}),"\n",(0,l.jsx)(s.h3,{id:"getdeclaringscope",children:"getDeclaringScope()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final Scope getDeclaringScope() {\n toGenerated(result) = this.(VariableReal).getDeclaringScopeImpl()\n }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the scope this variable is declared in."}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets an access to this variable."}),"\n",(0,l.jsx)(s.h2,{id:"localvariable",children:"LocalVariable"}),"\n",(0,l.jsxs)(s.p,{children:["A local variable. Extends ",(0,l.jsx)(s.code,{children:"Variable"}),"."]}),"\n",(0,l.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess-1",children:"getAnAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getdefiningaccess",children:"getDefiningAccess()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#iscaptured",children:"isCaptured"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-1",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"override LocalVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h3,{id:"getdefiningaccess",children:"getDefiningAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableAccess getDefiningAccess() {\n result = this.(LocalVariableReal).getDefiningAccessImpl() or\n synthChild(any(NamedParameter p | this = p.getVariable()), 0, result)\n }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the access where this local variable is first introduced."}),"\n",(0,l.jsx)(s.h3,{id:"iscaptured",children:"isCaptured()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate isCaptured() { this.getAnAccess().isCapturedAccess() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this variable is captured. For example in"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"def m x\n x.times do |y|\n puts x\n end\n puts x\nend\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.code,{children:"x"})," is a captured variable, whereas ",(0,l.jsx)(s.code,{children:"y"})," is not."]}),"\n",(0,l.jsx)(s.h2,{id:"globalvariable",children:"GlobalVariable"}),"\n",(0,l.jsxs)(s.p,{children:["A global variable. Extends ",(0,l.jsx)(s.code,{children:"Variable"}),"."]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess-2",children:"getAnAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-2",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final override GlobalVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"instancevariable",children:"InstanceVariable"}),"\n",(0,l.jsx)(s.p,{children:"An instance variable."}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#isclassinstancevariable",children:"isClassInstanceVariable()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess-3",children:"getAnAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"isclassinstancevariable",children:"isClassInstanceVariable()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate isClassInstanceVariable() { super.isClassInstanceVariable() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this variable is a class instance variable."}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-3",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final override InstanceVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"classvariable",children:"ClassVariable"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:"getAnAccess()"}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-4",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final override ClassVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"selfvariable",children:"SelfVariable"}),"\n",(0,l.jsxs)(s.p,{children:["A ",(0,l.jsx)(s.code,{children:"self"})," variable. Extends LocalVariable."]}),"\n",(0,l.jsx)(s.p,{children:"No methods yet."}),"\n",(0,l.jsx)(s.h2,{id:"variableaccess",children:"VariableAccess"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getvariable",children:"getVariable()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#isexplicitwriteastnode-assignment",children:"isExplicitWrite(AstNode assignment)"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#isimplicitwrite",children:"isImplicitWrite()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getvariable",children:"getVariable()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final Variable getVariable() { result = super.getVariableImpl() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the variable this identifier refers to."}),"\n",(0,l.jsx)(s.h3,{id:"isexplicitwriteastnode-assignment",children:"isExplicitWrite(AstNode assignment)"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"predicate isExplicitWrite(AstNode assignment) {\n explicitWriteAccess(toGenerated(this), toGenerated(assignment))\n or\n this = assignment.(AssignExpr).getLeftOperand()\n }\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Holds if this access is a write access belonging to the explicit assignment ",(0,l.jsx)(s.code,{children:"assignment"}),". For example, in"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"a, b = foo\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Both ",(0,l.jsx)(s.code,{children:"a"})," and ",(0,l.jsx)(s.code,{children:"b"})," are write accesses belonging to the same assignment."]}),"\n",(0,l.jsx)(s.h3,{id:"isimplicitwrite",children:"isImplicitWrite()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"predicate isImplicitWrite() {\n implicitWriteAccess(toGenerated(this))\n or\n this = any(SimpleParameterSynthImpl p).getDefiningAccess()\n or\n this = any(HashPattern p).getValue(_)\n or\n synthChild(any(NamedParameter p), 0, this)\n}\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this access is a write access belonging to an implicit assignment.\nFor example, in"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"def m elements\n for e in elements do\n puts e\n end\nend\n"})}),"\n",(0,l.jsxs)(s.p,{children:["The access to ",(0,l.jsx)(s.code,{children:"elements"})," in the parameter list is an implicit assignment,\nas is the first access to ",(0,l.jsx)(s.code,{children:"e"}),"."]}),"\n",(0,l.jsx)(s.h2,{id:"variablewriteaccess",children:"VariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a variable where the value is updated."}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableWriteAccess() {\n this.isExplicitWrite(_) or\n this.isImplicitWrite()\n }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"variablereadaccess",children:"VariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a variable where the value is read."}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableReadAccess() { not this instanceof VariableWriteAccess }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"localvariableaccess",children:"LocalVariableAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a local variable."}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getaprimaryqlclasses",children:"getAPrimaryQlClass()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#iscapturedaccess",children:"isCapturedAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclasses",children:"getAPrimaryQlClasses()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "LocalVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.h3,{id:"iscapturedaccess",children:"isCapturedAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate isCapturedAccess() { isCapturedAccess(this) }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this access is a captured variable access. For example in"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"def m x\n x.times do |y|\n puts x\n end\n puts x\nend\n"})}),"\n",(0,l.jsxs)(s.p,{children:["The access to ",(0,l.jsx)(s.code,{children:"x"})," in the first ",(0,l.jsx)(s.code,{children:"puts x"})," is a captured access, while the access to ",(0,l.jsx)(s.code,{children:"x"})," in the second ",(0,l.jsx)(s.code,{children:"puts x"})," is not."]}),"\n",(0,l.jsx)(s.h2,{id:"localvariablewriteaccess",children:"LocalVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"localvariablereadaccess",children:"LocalVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"globalvariableaccess",children:"GlobalVariableAccess"}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "GlobalVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.h2,{id:"globalvariablewriteaccess",children:"GlobalVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"globalvariablereadaccess",children:"GlobalVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"instancevariableaccess",children:"InstanceVariableAccess"}),"\n",(0,l.jsxs)(s.p,{children:["An access to an instance variable. Extends ",(0,l.jsx)(s.code,{children:"VariableAccess"}),"."]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getreceiver",children:"getReceiver()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getachildstring-pred",children:"getAChild(string pred)"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "InstanceVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.h3,{id:"getreceiver",children:"getReceiver()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final SelfVariableAccess getReceiver() { synthChild(this, 0, result) }\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Gets the synthetic receiver (",(0,l.jsx)(s.code,{children:"self"}),") of this instance variable access."]}),"\n",(0,l.jsx)(s.h3,{id:"getachildstring-pred",children:"getAChild(string pred)"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override AstNode getAChild(string pred) {\n result = VariableAccess.super.getAChild(pred)\n or\n pred = "getReceiver" and result = this.getReceiver()\n}\n'})}),"\n",(0,l.jsx)(s.h2,{id:"instancevariablewriteaccess",children:"InstanceVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"instancevariablereadaccess",children:"InstanceVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"classvariableaccess",children:"ClassVariableAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a class variable."}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "ClassVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.p,{children:"Gets the name of the class."}),"\n",(0,l.jsx)(s.h2,{id:"classvariablewriteaccess",children:"ClassVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"classvariablereadaccess",children:"ClassVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"selfvariableaccess",children:"SelfVariableAccess"}),"\n",(0,l.jsxs)(s.p,{children:["An access to the ",(0,l.jsx)(s.code,{children:"self"})," variable. For example:"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.code,{children:"self == other"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.code,{children:"self.method_name"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.code,{children:"def self.method_name ... end"})}),"\n"]}),"\n",(0,l.jsxs)(s.p,{children:["This also includes implicit references to the current object in method\ncalls. For example, the method call ",(0,l.jsx)(s.code,{children:"foo(123)"})," has an implicit ",(0,l.jsx)(s.code,{children:"self"}),"\nreceiver, and is equivalent to the explicit ",(0,l.jsx)(s.code,{children:"self.foo(123)"}),"."]}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "SelfVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.p,{children:"Gets name of the class."}),"\n",(0,l.jsx)(s.h2,{id:"selfvariablereadaccess",children:"SelfVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."})]})}function x(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,l.jsx)(s,{...e,children:(0,l.jsx)(h,{...e})}):h(e)}},1503:(e,s,a)=>{a.d(s,{R:()=>r,x:()=>n});var l=a(758);const i={},c=l.createContext(i);function r(e){const s=l.useContext(c);return l.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function n(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),l.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/94ad6ac6.3822a12f.js b/assets/js/94ad6ac6.3822a12f.js new file mode 100644 index 0000000..ff6343a --- /dev/null +++ b/assets/js/94ad6ac6.3822a12f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[487],{4016:(e,s,a)=>{a.r(s),a.d(s,{assets:()=>d,contentTitle:()=>r,default:()=>x,frontMatter:()=>c,metadata:()=>n,toc:()=>t});var l=a(6070),i=a(1503);const c={},r="Variable",n={id:"Classes/Variable",title:"Variable",description:"Classes",source:"@site/docs/Classes/Variable.md",sourceDirName:"Classes",slug:"/Classes/Variable",permalink:"/CyScout/docs/Classes/Variable",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Variable.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"SubBasicBlock",permalink:"/CyScout/docs/Classes/SubBasicBlock"},next:{title:"Index",permalink:"/CyScout/docs/Classes/classesIndex"}},d={},t=[{value:"Classes",id:"classes",level:2},{value:"Variable",id:"variable-1",level:2},{value:"getName()",id:"getname",level:3},{value:"hasName()",id:"hasname",level:3},{value:"toString()",id:"tostring",level:3},{value:"getLocation()",id:"getlocation",level:3},{value:"getDeclaringScope()",id:"getdeclaringscope",level:3},{value:"getAnAccess()",id:"getanaccess",level:3},{value:"LocalVariable",id:"localvariable",level:2},{value:"Methods",id:"methods",level:3},{value:"getAnAccess()",id:"getanaccess-1",level:3},{value:"getDefiningAccess()",id:"getdefiningaccess",level:3},{value:"isCaptured()",id:"iscaptured",level:3},{value:"GlobalVariable",id:"globalvariable",level:2},{value:"getAnAccess()",id:"getanaccess-2",level:3},{value:"InstanceVariable",id:"instancevariable",level:2},{value:"isClassInstanceVariable()",id:"isclassinstancevariable",level:3},{value:"getAnAccess()",id:"getanaccess-3",level:3},{value:"ClassVariable",id:"classvariable",level:2},{value:"getAnAccess()",id:"getanaccess-4",level:3},{value:"SelfVariable",id:"selfvariable",level:2},{value:"VariableAccess",id:"variableaccess",level:2},{value:"getVariable()",id:"getvariable",level:3},{value:"isExplicitWrite(AstNode assignment)",id:"isexplicitwriteastnode-assignment",level:3},{value:"isImplicitWrite()",id:"isimplicitwrite",level:3},{value:"VariableWriteAccess",id:"variablewriteaccess",level:2},{value:"VariableReadAccess",id:"variablereadaccess",level:2},{value:"LocalVariableAccess",id:"localvariableaccess",level:2},{value:"getAPrimaryQlClasses()",id:"getaprimaryqlclasses",level:3},{value:"isCapturedAccess()",id:"iscapturedaccess",level:3},{value:"LocalVariableWriteAccess",id:"localvariablewriteaccess",level:2},{value:"LocalVariableReadAccess",id:"localvariablereadaccess",level:2},{value:"GlobalVariableAccess",id:"globalvariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"GlobalVariableWriteAccess",id:"globalvariablewriteaccess",level:2},{value:"GlobalVariableReadAccess",id:"globalvariablereadaccess",level:2},{value:"InstanceVariableAccess",id:"instancevariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"getReceiver()",id:"getreceiver",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred",level:3},{value:"InstanceVariableWriteAccess",id:"instancevariablewriteaccess",level:2},{value:"InstanceVariableReadAccess",id:"instancevariablereadaccess",level:2},{value:"ClassVariableAccess",id:"classvariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"ClassVariableWriteAccess",id:"classvariablewriteaccess",level:2},{value:"ClassVariableReadAccess",id:"classvariablereadaccess",level:2},{value:"SelfVariableAccess",id:"selfvariableaccess",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3},{value:"SelfVariableReadAccess",id:"selfvariablereadaccess",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.header,{children:(0,l.jsx)(s.h1,{id:"variable",children:"Variable"})}),"\n",(0,l.jsx)(s.h2,{id:"classes",children:"Classes"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variable-1",children:"Variable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariable",children:"LocalVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariable",children:"GlobalVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariable",children:"InstanceVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariable",children:"ClassVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#selfvariable",children:"SelfVariable"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variableaccess",children:"VariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variablewriteaccess",children:"VariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#variablereadaccess",children:"VariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariableaccess",children:"LocalVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariablewriteaccess",children:"LocalVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#localvariablereadaccess",children:"LocalVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariableaccess",children:"GlobalVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariablewriteaccess",children:"GlobalVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#globalvariablewriteaccess",children:"GlobalVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariableaccess",children:"InstanceVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariablewriteaccess",children:"InstanceVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#instancevariablereadaccess",children:"InstanceVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariableaccess",children:"ClassVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariablewriteaccess",children:"ClassVariableWriteAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#classvariablereadaccess",children:"ClassVariableReadAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#selfvariableaccess",children:"SelfVariableAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#selfvariablereadaccess",children:"SelfVariableReadAccess"})}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"variable-1",children:"Variable"}),"\n",(0,l.jsx)(s.p,{children:"A variable declared in a scope."}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getname",children:"getName()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#hasname",children:"hasName()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#tostring",children:"toString()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getlocation",children:"getLocation()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getdeclaringscope",children:"getDeclaringScope()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess",children:"getAnAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getname",children:"getName()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final string getName() { result = super.getNameImpl() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the name of this variable."}),"\n",(0,l.jsx)(s.h3,{id:"hasname",children:"hasName()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate hasName(string name) { this.getName() = name }\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Holds if the name of this variable is a ",(0,l.jsx)(s.code,{children:"name"}),"."]}),"\n",(0,l.jsx)(s.h3,{id:"tostring",children:"toString()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final string toString() { result = this.getName() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets a textual representation of this variable."}),"\n",(0,l.jsx)(s.h3,{id:"getlocation",children:"getLocation()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final Location getLocation() { result = super.getLocationImpl() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the location of this variable."}),"\n",(0,l.jsx)(s.h3,{id:"getdeclaringscope",children:"getDeclaringScope()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final Scope getDeclaringScope() {\n toGenerated(result) = this.(VariableReal).getDeclaringScopeImpl()\n }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the scope this variable is declared in."}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets an access to this variable."}),"\n",(0,l.jsx)(s.h2,{id:"localvariable",children:"LocalVariable"}),"\n",(0,l.jsxs)(s.p,{children:["A local variable. Extends ",(0,l.jsx)(s.code,{children:"Variable"}),"."]}),"\n",(0,l.jsx)(s.h3,{id:"methods",children:"Methods"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess-1",children:"getAnAccess"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getdefiningaccess",children:"getDefiningAccess()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#iscaptured",children:"isCaptured"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-1",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"override LocalVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h3,{id:"getdefiningaccess",children:"getDefiningAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableAccess getDefiningAccess() {\n result = this.(LocalVariableReal).getDefiningAccessImpl() or\n synthChild(any(NamedParameter p | this = p.getVariable()), 0, result)\n }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the access where this local variable is first introduced."}),"\n",(0,l.jsx)(s.h3,{id:"iscaptured",children:"isCaptured()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate isCaptured() { this.getAnAccess().isCapturedAccess() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this variable is captured. For example in"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"def m x\n x.times do |y|\n puts x\n end\n puts x\nend\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.code,{children:"x"})," is a captured variable, whereas ",(0,l.jsx)(s.code,{children:"y"})," is not."]}),"\n",(0,l.jsx)(s.h2,{id:"globalvariable",children:"GlobalVariable"}),"\n",(0,l.jsxs)(s.p,{children:["A global variable. Extends ",(0,l.jsx)(s.code,{children:"Variable"}),"."]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess-2",children:"getAnAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-2",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final override GlobalVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"instancevariable",children:"InstanceVariable"}),"\n",(0,l.jsx)(s.p,{children:"An instance variable."}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#isclassinstancevariable",children:"isClassInstanceVariable()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getanaccess-3",children:"getAnAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"isclassinstancevariable",children:"isClassInstanceVariable()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate isClassInstanceVariable() { super.isClassInstanceVariable() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this variable is a class instance variable."}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-3",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final override InstanceVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"classvariable",children:"ClassVariable"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:"getAnAccess()"}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getanaccess-4",children:"getAnAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final override ClassVariableAccess getAnAccess() { result.getVariable() = this }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"selfvariable",children:"SelfVariable"}),"\n",(0,l.jsxs)(s.p,{children:["A ",(0,l.jsx)(s.code,{children:"self"})," variable. Extends LocalVariable."]}),"\n",(0,l.jsx)(s.p,{children:"No methods yet."}),"\n",(0,l.jsx)(s.h2,{id:"variableaccess",children:"VariableAccess"}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getvariable",children:"getVariable()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#isexplicitwriteastnode-assignment",children:"isExplicitWrite(AstNode assignment)"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#isimplicitwrite",children:"isImplicitWrite()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getvariable",children:"getVariable()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final Variable getVariable() { result = super.getVariableImpl() }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Gets the variable this identifier refers to."}),"\n",(0,l.jsx)(s.h3,{id:"isexplicitwriteastnode-assignment",children:"isExplicitWrite(AstNode assignment)"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"predicate isExplicitWrite(AstNode assignment) {\n explicitWriteAccess(toGenerated(this), toGenerated(assignment))\n or\n this = assignment.(AssignExpr).getLeftOperand()\n }\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Holds if this access is a write access belonging to the explicit assignment ",(0,l.jsx)(s.code,{children:"assignment"}),". For example, in"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"a, b = foo\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Both ",(0,l.jsx)(s.code,{children:"a"})," and ",(0,l.jsx)(s.code,{children:"b"})," are write accesses belonging to the same assignment."]}),"\n",(0,l.jsx)(s.h3,{id:"isimplicitwrite",children:"isImplicitWrite()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"predicate isImplicitWrite() {\n implicitWriteAccess(toGenerated(this))\n or\n this = any(SimpleParameterSynthImpl p).getDefiningAccess()\n or\n this = any(HashPattern p).getValue(_)\n or\n synthChild(any(NamedParameter p), 0, this)\n}\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this access is a write access belonging to an implicit assignment.\nFor example, in"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"def m elements\n for e in elements do\n puts e\n end\nend\n"})}),"\n",(0,l.jsxs)(s.p,{children:["The access to ",(0,l.jsx)(s.code,{children:"elements"})," in the parameter list is an implicit assignment,\nas is the first access to ",(0,l.jsx)(s.code,{children:"e"}),"."]}),"\n",(0,l.jsx)(s.h2,{id:"variablewriteaccess",children:"VariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a variable where the value is updated."}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableWriteAccess() {\n this.isExplicitWrite(_) or\n this.isImplicitWrite()\n }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"variablereadaccess",children:"VariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a variable where the value is read."}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"VariableReadAccess() { not this instanceof VariableWriteAccess }\n"})}),"\n",(0,l.jsx)(s.h2,{id:"localvariableaccess",children:"LocalVariableAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a local variable."}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getaprimaryqlclasses",children:"getAPrimaryQlClass()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#iscapturedaccess",children:"isCapturedAccess()"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclasses",children:"getAPrimaryQlClasses()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'override string getAPrimaryQlClass() { result = "LocalVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.h3,{id:"iscapturedaccess",children:"isCapturedAccess()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final predicate isCapturedAccess() { isCapturedAccess(this) }\n"})}),"\n",(0,l.jsx)(s.p,{children:"Holds if this access is a captured variable access. For example in"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-rb",children:"def m x\n x.times do |y|\n puts x\n end\n puts x\nend\n"})}),"\n",(0,l.jsxs)(s.p,{children:["The access to ",(0,l.jsx)(s.code,{children:"x"})," in the first ",(0,l.jsx)(s.code,{children:"puts x"})," is a captured access, while the access to ",(0,l.jsx)(s.code,{children:"x"})," in the second ",(0,l.jsx)(s.code,{children:"puts x"})," is not."]}),"\n",(0,l.jsx)(s.h2,{id:"localvariablewriteaccess",children:"LocalVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"localvariablereadaccess",children:"LocalVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"globalvariableaccess",children:"GlobalVariableAccess"}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "GlobalVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.h2,{id:"globalvariablewriteaccess",children:"GlobalVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"globalvariablereadaccess",children:"GlobalVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"instancevariableaccess",children:"InstanceVariableAccess"}),"\n",(0,l.jsxs)(s.p,{children:["An access to an instance variable. Extends ",(0,l.jsx)(s.code,{children:"VariableAccess"}),"."]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getreceiver",children:"getReceiver()"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.a,{href:"#getachildstring-pred",children:"getAChild(string pred)"})}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "InstanceVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.h3,{id:"getreceiver",children:"getReceiver()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:"final SelfVariableAccess getReceiver() { synthChild(this, 0, result) }\n"})}),"\n",(0,l.jsxs)(s.p,{children:["Gets the synthetic receiver (",(0,l.jsx)(s.code,{children:"self"}),") of this instance variable access."]}),"\n",(0,l.jsx)(s.h3,{id:"getachildstring-pred",children:"getAChild(string pred)"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override AstNode getAChild(string pred) {\n result = VariableAccess.super.getAChild(pred)\n or\n pred = "getReceiver" and result = this.getReceiver()\n}\n'})}),"\n",(0,l.jsx)(s.h2,{id:"instancevariablewriteaccess",children:"InstanceVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"instancevariablereadaccess",children:"InstanceVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"classvariableaccess",children:"ClassVariableAccess"}),"\n",(0,l.jsx)(s.p,{children:"An access to a class variable."}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "ClassVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.p,{children:"Gets the name of the class."}),"\n",(0,l.jsx)(s.h2,{id:"classvariablewriteaccess",children:"ClassVariableWriteAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"classvariablereadaccess",children:"ClassVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."}),"\n",(0,l.jsx)(s.h2,{id:"selfvariableaccess",children:"SelfVariableAccess"}),"\n",(0,l.jsxs)(s.p,{children:["An access to the ",(0,l.jsx)(s.code,{children:"self"})," variable. For example:"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.code,{children:"self == other"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.code,{children:"self.method_name"})}),"\n",(0,l.jsx)(s.li,{children:(0,l.jsx)(s.code,{children:"def self.method_name ... end"})}),"\n"]}),"\n",(0,l.jsxs)(s.p,{children:["This also includes implicit references to the current object in method\ncalls. For example, the method call ",(0,l.jsx)(s.code,{children:"foo(123)"})," has an implicit ",(0,l.jsx)(s.code,{children:"self"}),"\nreceiver, and is equivalent to the explicit ",(0,l.jsx)(s.code,{children:"self.foo(123)"}),"."]}),"\n",(0,l.jsx)(s.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{children:'final override string getAPrimaryQlClass() { result = "SelfVariableAccess" }\n'})}),"\n",(0,l.jsx)(s.p,{children:"Gets name of the class."}),"\n",(0,l.jsx)(s.h2,{id:"selfvariablereadaccess",children:"SelfVariableReadAccess"}),"\n",(0,l.jsx)(s.p,{children:"Not implemented yet."})]})}function x(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,l.jsx)(s,{...e,children:(0,l.jsx)(h,{...e})}):h(e)}},1503:(e,s,a)=>{a.d(s,{R:()=>r,x:()=>n});var l=a(758);const i={},c=l.createContext(i);function r(e){const s=l.useContext(c);return l.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function n(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),l.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9567510c.04bf2443.js b/assets/js/9567510c.04bf2443.js deleted file mode 100644 index 18419db..0000000 --- a/assets/js/9567510c.04bf2443.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[165],{428:(e,l,r)=>{r.r(l),r.d(l,{assets:()=>a,contentTitle:()=>i,default:()=>o,frontMatter:()=>t,metadata:()=>d,toc:()=>c});var n=r(6070),s=r(1503);const t={},i="Call",d={id:"Classes/Call",title:"Call",description:"Classes",source:"@site/docs/Classes/Call.md",sourceDirName:"Classes",slug:"/Classes/Call",permalink:"/docs/Classes/Call",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Call.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Block Statement",permalink:"/docs/Classes/Block"},next:{title:"Control Flow Graph",permalink:"/docs/Classes/ControlFlowGraph"}},a={},c=[{value:"Classes",id:"classes",level:2},{value:"Call",id:"call-1",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"getArgument(int n)",id:"getargumentint-n",level:3},{value:"getAnArgument()",id:"getanargument",level:3},{value:"getKeywordArgument(string keyword)",id:"getkeywordargumentstring-keyword",level:3},{value:"getNumberOfArguments()",id:"getnumberofarguments",level:3},{value:"getATarget()",id:"getatarget",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred",level:3},{value:"MethodCall",id:"methodcall",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"getReceiver()",id:"getreceiver",level:3},{value:"getMethodName()",id:"getmethodname",level:3},{value:"getBlock()",id:"getblock",level:3},{value:"getBlockArgument()",id:"getblockargument",level:3},{value:"hasBlock()",id:"hasblock",level:3},{value:"isSafeNavigation()",id:"issafenavigation",level:3},{value:"toString()",id:"tostring",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred-1",level:3},{value:"UnknownMethodCall",id:"unknownmethodcall",level:2},{value:"UnknownMethodCall",id:"unknownmethodcall-1",level:3},{value:"SetterMethodCall",id:"settermethodcall",level:2},{value:"SetterMethodCall()",id:"settermethodcall-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"getTargetName()",id:"gettargetname",level:3},{value:"ElementReference",id:"elementreference",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3},{value:"toString()",id:"tostring-1",level:3},{value:"YieldCall",id:"yieldcall",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-4",level:3},{value:"toString()",id:"tostring-2",level:3},{value:"SuperCall",id:"supercall",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-5",level:3},{value:"toString()",id:"tostring-3",level:3},{value:"BlockArgument",id:"blockargument",level:2},{value:"BlockArgument()",id:"blockargument-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-6",level:3},{value:"getValue()",id:"getvalue",level:3},{value:"toString()",id:"tostring-4",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred-2",level:3},{value:"ForwardedArguments",id:"forwardedarguments",level:2},{value:"ForwardedArguments()",id:"forwardedarguments-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-7",level:3},{value:"toString()",id:"tostring-5",level:3}];function h(e){const l={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(l.header,{children:(0,n.jsx)(l.h1,{id:"call",children:"Call"})}),"\n",(0,n.jsx)(l.h2,{id:"classes",children:"Classes"}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#call",children:"Call"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#methodcall",children:"MethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#unknownmethodcall",children:"UnknownMethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#settermethodcall",children:"SetterMethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#elementreference",children:"ElementReference"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#yieldcall",children:"YieldCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#supercall",children:"SuperCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#blockargument",children:"BlockArgument"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#forwardedarguments",children:"ForwardedArguments"})}),"\n"]}),"\n",(0,n.jsx)(l.h2,{id:"call-1",children:"Call"}),"\n",(0,n.jsx)(l.p,{children:"Extends Expr instanceof CallImpl"}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getargumentint-n",children:"getArgument(int n)"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getanargument",children:"getAnArgument()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getkeywordargumentstring-keyword",children:"getKeywordArgument(string keyword)"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getnumberofarguments",children:"getNumberOfArguments()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getatarget",children:"getATarget()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getachildstring-pred",children:"getAChild(string pred)"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string getAPrimaryQlClass() { result = "Call" }\n'})}),"\n",(0,n.jsx)(l.p,{children:"Returns the kind of the class."}),"\n",(0,n.jsx)(l.h3,{id:"getargumentint-n",children:"getArgument(int n)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getArgument(int n) { result = super.getArgumentImpl(n) }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the ",(0,n.jsx)(l.code,{children:"n"}),"th argument of this method call. For instance,"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"foo(0, bar: 1)\nyield 0, bar: 1\n"})}),"\n",(0,n.jsxs)(l.p,{children:["For ",(0,n.jsx)(l.code,{children:"getArgument(0)"})," the result is the ",(0,n.jsx)(l.code,{children:"IntegerLiteral"})," 0. While for ",(0,n.jsx)(l.code,{children:"getArgument(1)"})," the result is a ",(0,n.jsx)(l.code,{children:"Pair"}),"."]}),"\n",(0,n.jsx)(l.h3,{id:"getanargument",children:"getAnArgument()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getAnArgument() { result = this.getArgument(_) }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets an argument of this method call."}),"\n",(0,n.jsx)(l.h3,{id:"getkeywordargumentstring-keyword",children:"getKeywordArgument(string keyword)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getKeywordArgument(string keyword) {\n exists(Pair p |\n p = this.getAnArgument() and\n p.getKey().getConstantValue().isSymbol(keyword) and\n result = p.getValue()\n )\n }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the value of the keyword argument whose key is ",(0,n.jsx)(l.code,{children:"keyword"}),", if any."]}),"\n",(0,n.jsxs)(l.p,{children:["For example, the result for ",(0,n.jsx)(l.code,{children:'getKeywordArgument("qux")'})," in the following example is the ",(0,n.jsx)(l.code,{children:"IntegerLiteral"})," 123."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:'foo :bar "baz", qux: 123\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getnumberofarguments",children:"getNumberOfArguments()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final int getNumberOfArguments() { result = super.getNumberOfArgumentsImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the number of arguments of this method call."}),"\n",(0,n.jsx)(l.h3,{id:"getatarget",children:"getATarget()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Callable getATarget() {\n exists(DataFlowCall c |\n this = c.asCall().getExpr() and\n TCfgScope(result) = viableCallableLambda(c, _)\n )\n or\n result = getTarget(TNormalCall(this.getAControlFlowNode()))\n }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets a potential target of this call, if any."}),"\n",(0,n.jsx)(l.h3,{id:"getachildstring-pred",children:"getAChild(string pred)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override AstNode getAChild(string pred) {\n result = Expr.super.getAChild(pred)\n or\n pred = "getArgument" and result = this.getArgument(_)\n}\n\n'})}),"\n",(0,n.jsx)(l.p,{children:"Gets a child of the predicate passed by argument."}),"\n",(0,n.jsx)(l.h2,{id:"methodcall",children:"MethodCall"}),"\n",(0,n.jsx)(l.p,{children:"A method call."}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getreceiver",children:"getReceiver()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getmethodname",children:"getMethodName()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getblock",children:"getBlock()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getblockargument",children:"getBlockArgument()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#hasblock",children:"hasBlock()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#issafenavigation",children:"isSafeNavigation()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring",children:"toString()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getachildstring-pred-1",children:"getAChild(string pred)"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string getAPrimaryQlClass() { result = "MethodCall" }\n'})}),"\n",(0,n.jsx)(l.p,{children:"Returns the kind of the class."}),"\n",(0,n.jsx)(l.h3,{id:"getreceiver",children:"getReceiver()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getReceiver() { result = super.getReceiverImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the receiver of this call, if any. For example:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.bar\nBaz::qux\ncorge()\n"})}),"\n",(0,n.jsxs)(l.p,{children:["The result for the call to ",(0,n.jsx)(l.code,{children:"bar"})," is the ",(0,n.jsx)(l.code,{children:"Expr"})," for ",(0,n.jsx)(l.code,{children:"foo"}),"; the result for the call to ",(0,n.jsx)(l.code,{children:"qux"})," is the ",(0,n.jsx)(l.code,{children:"Expr"})," for ",(0,n.jsx)(l.code,{children:"Baz"}),"; for the call to ",(0,n.jsx)(l.code,{children:"corge"})," there is no result."]}),"\n",(0,n.jsx)(l.h3,{id:"getmethodname",children:"getMethodName()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final string getMethodName() { result = super.getMethodNameImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the name of the method being called. For example, in:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.bar x, y\n"})}),"\n",(0,n.jsxs)(l.p,{children:["The result is ",(0,n.jsx)(l.code,{children:'"bar"'}),". Super calls call a method with the same name as the current method, so the result for a super call is the name of the current method."]}),"\n",(0,n.jsx)(l.p,{children:"E.g:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:'def foo\n super # the result for this super call is "foo"\nend\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getblock",children:"getBlock()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Block getBlock() { result = super.getBlockImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the block of this method call, if any."}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.each { |x| puts x }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getblockargument",children:"getBlockArgument()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final BlockArgument getBlockArgument() { result = this.getAnArgument() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the block argument of this method call, if any."}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo(&block)\n"})}),"\n",(0,n.jsx)(l.h3,{id:"hasblock",children:"hasBlock()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final predicate hasBlock() { exists(this.getBlock()) or exists(this.getBlockArgument()) }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Holds if this method call has a block or block argument."}),"\n",(0,n.jsx)(l.h3,{id:"issafenavigation",children:"isSafeNavigation()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final predicate isSafeNavigation() { super.isSafeNavigationImpl() }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Holds if the safe navigation operator (",(0,n.jsx)(l.code,{children:"&."}),") is used in this call."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo&.empty?\n"})}),"\n",(0,n.jsx)(l.h3,{id:"tostring",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string toString() { result = "call to " + this.getMethodName() }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getachildstring-pred-1",children:"getAChild(string pred)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override AstNode getAChild(string pred) {\n result = Call.super.getAChild(pred)\n or\n pred = "getReceiver" and result = this.getReceiver()\n or\n pred = "getBlock" and result = this.getBlock()\n }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"unknownmethodcall",children:"UnknownMethodCall"}),"\n",(0,n.jsx)(l.p,{children:"Extends MethodCall"}),"\n",(0,n.jsxs)(l.p,{children:["A ",(0,n.jsx)(l.code,{children:"Method"})," call that has no known target. These will typically be calls to methods inherited from a superclass."]}),"\n",(0,n.jsxs)(l.p,{children:["Diclaimer: When API Graphs is able to resolve calls to methods like ",(0,n.jsx)(l.code,{children:"Kernel.send"})," this class is no longer necessary and should be removed."]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#unknownmethodcall-1",children:"UnknownMethodCall"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"unknownmethodcall-1",children:"UnknownMethodCall"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"UnknownMethodCall() { not exists(this.(Call).getATarget()) }\n"})}),"\n",(0,n.jsx)(l.h2,{id:"settermethodcall",children:"SetterMethodCall"}),"\n",(0,n.jsxs)(l.p,{children:["A call to a setter method. This class extends ",(0,n.jsx)(l.code,{children:"MethodCall"})," and ",(0,n.jsx)(l.code,{children:"TMethodCallSynth"}),"."]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#settermethodcall",children:"SetterMethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-2",children:"getAPrimaryQlClass"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#gettargetname",children:"getTargetName()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"settermethodcall-1",children:"SetterMethodCall()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"SetterMethodCall() { this = TMethodCallSynth(_, _, _, true, _) }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "SetterMethodCall" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"gettargetname",children:"getTargetName()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final string getTargetName() {\n exists(string methodName |\n methodName = this.getMethodName() and\n result = methodName.prefix(methodName.length() - 1)\n )\n }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the name of the method being called without the trailing ",(0,n.jsx)(l.code,{children:"="}),". For example, in the following two statements the target name is ",(0,n.jsx)(l.code,{children:"value"}),":"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.value=(1)\nfoo.value = 1\n"})}),"\n",(0,n.jsx)(l.h2,{id:"elementreference",children:"ElementReference"}),"\n",(0,n.jsxs)(l.p,{children:["An element reference; a call to the ",(0,n.jsx)(l.code,{children:"[]"})," method."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"a[0]\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Extends ",(0,n.jsx)(l.code,{children:"MethodCall"})]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-3",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-1",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "ElementReference" }\n'})}),"\n",(0,n.jsx)(l.p,{children:"Returns the kind of the class."}),"\n",(0,n.jsx)(l.h3,{id:"tostring-1",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "...[...]" }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"yieldcall",children:"YieldCall"}),"\n",(0,n.jsxs)(l.p,{children:["A call to yield. Extends ",(0,n.jsx)(l.code,{children:"Call"})," class."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"yield x, y\n"})}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-4",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-2",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-4",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "YieldCall" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-2",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "yield ..." }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"supercall",children:"SuperCall"}),"\n",(0,n.jsxs)(l.p,{children:["A call to ",(0,n.jsx)(l.code,{children:"super"}),"."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"class Foo < Bar\n def baz\n super\n end\nend\n"})}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-5",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-3",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-5",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "SuperCall" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-3",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string toString() { result = "super call to " + this.getMethodName() }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"blockargument",children:"BlockArgument"}),"\n",(0,n.jsxs)(l.p,{children:["A block argument in a method call. It extends ",(0,n.jsx)(l.code,{children:"Expr"})]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#blockargument-1",children:"BlockArgument()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-6",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getvalue",children:"getValue()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-4",children:"toString()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getachildstring-pred-2",children:"getAChild()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"blockargument-1",children:"BlockArgument()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"BlockArgument() { this = TBlockArgument(g) }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-6",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "BlockArgument" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getvalue",children:"getValue()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getValue() {\n toGenerated(result) = g.getChild() or\n synthChild(this, 0, result)\n }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the underlying expression representing the block. In the following example, the result is the ",(0,n.jsx)(l.code,{children:"Expr"})," for ",(0,n.jsx)(l.code,{children:"bar"}),":"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo(&bar)\n"})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-4",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "&..." }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getachildstring-pred-2",children:"getAChild(string pred)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override AstNode getAChild(string pred) {\n result = super.getAChild(pred)\n or\n pred = "getValue" and result = this.getValue()\n }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"forwardedarguments",children:"ForwardedArguments"}),"\n",(0,n.jsxs)(l.p,{children:["A ",(0,n.jsx)(l.code,{children:"..."})," expression that contains forwarded arguments. This class extends ",(0,n.jsx)(l.code,{children:"Expr"}),"."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo(...)\n"})}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#forwardedarguments-1",children:"ForwardedArguments()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-7",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-5",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"forwardedarguments-1",children:"ForwardedArguments()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"ForwardedArguments() { this = TForwardArgument(g) }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-7",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "ForwardedArguments" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-5",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "..." }\n'})}),"\n",(0,n.jsxs)(l.p,{children:["A ",(0,n.jsx)(l.code,{children:"..."})," expression that contains forwarded arguments."]})]})}function o(e={}){const{wrapper:l}={...(0,s.R)(),...e.components};return l?(0,n.jsx)(l,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1503:(e,l,r)=>{r.d(l,{R:()=>i,x:()=>d});var n=r(758);const s={},t=n.createContext(s);function i(e){const l=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(l):{...l,...e}}),[l,e])}function d(e){let l;return l=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(t.Provider,{value:l},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9567510c.f3645756.js b/assets/js/9567510c.f3645756.js new file mode 100644 index 0000000..bbcb29f --- /dev/null +++ b/assets/js/9567510c.f3645756.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[165],{428:(e,l,r)=>{r.r(l),r.d(l,{assets:()=>a,contentTitle:()=>i,default:()=>o,frontMatter:()=>t,metadata:()=>d,toc:()=>c});var n=r(6070),s=r(1503);const t={},i="Call",d={id:"Classes/Call",title:"Call",description:"Classes",source:"@site/docs/Classes/Call.md",sourceDirName:"Classes",slug:"/Classes/Call",permalink:"/CyScout/docs/Classes/Call",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Call.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Block Statement",permalink:"/CyScout/docs/Classes/Block"},next:{title:"Control Flow Graph",permalink:"/CyScout/docs/Classes/ControlFlowGraph"}},a={},c=[{value:"Classes",id:"classes",level:2},{value:"Call",id:"call-1",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass",level:3},{value:"getArgument(int n)",id:"getargumentint-n",level:3},{value:"getAnArgument()",id:"getanargument",level:3},{value:"getKeywordArgument(string keyword)",id:"getkeywordargumentstring-keyword",level:3},{value:"getNumberOfArguments()",id:"getnumberofarguments",level:3},{value:"getATarget()",id:"getatarget",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred",level:3},{value:"MethodCall",id:"methodcall",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-1",level:3},{value:"getReceiver()",id:"getreceiver",level:3},{value:"getMethodName()",id:"getmethodname",level:3},{value:"getBlock()",id:"getblock",level:3},{value:"getBlockArgument()",id:"getblockargument",level:3},{value:"hasBlock()",id:"hasblock",level:3},{value:"isSafeNavigation()",id:"issafenavigation",level:3},{value:"toString()",id:"tostring",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred-1",level:3},{value:"UnknownMethodCall",id:"unknownmethodcall",level:2},{value:"UnknownMethodCall",id:"unknownmethodcall-1",level:3},{value:"SetterMethodCall",id:"settermethodcall",level:2},{value:"SetterMethodCall()",id:"settermethodcall-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-2",level:3},{value:"getTargetName()",id:"gettargetname",level:3},{value:"ElementReference",id:"elementreference",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-3",level:3},{value:"toString()",id:"tostring-1",level:3},{value:"YieldCall",id:"yieldcall",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-4",level:3},{value:"toString()",id:"tostring-2",level:3},{value:"SuperCall",id:"supercall",level:2},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-5",level:3},{value:"toString()",id:"tostring-3",level:3},{value:"BlockArgument",id:"blockargument",level:2},{value:"BlockArgument()",id:"blockargument-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-6",level:3},{value:"getValue()",id:"getvalue",level:3},{value:"toString()",id:"tostring-4",level:3},{value:"getAChild(string pred)",id:"getachildstring-pred-2",level:3},{value:"ForwardedArguments",id:"forwardedarguments",level:2},{value:"ForwardedArguments()",id:"forwardedarguments-1",level:3},{value:"getAPrimaryQlClass()",id:"getaprimaryqlclass-7",level:3},{value:"toString()",id:"tostring-5",level:3}];function h(e){const l={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(l.header,{children:(0,n.jsx)(l.h1,{id:"call",children:"Call"})}),"\n",(0,n.jsx)(l.h2,{id:"classes",children:"Classes"}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#call",children:"Call"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#methodcall",children:"MethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#unknownmethodcall",children:"UnknownMethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#settermethodcall",children:"SetterMethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#elementreference",children:"ElementReference"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#yieldcall",children:"YieldCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#supercall",children:"SuperCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#blockargument",children:"BlockArgument"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#forwardedarguments",children:"ForwardedArguments"})}),"\n"]}),"\n",(0,n.jsx)(l.h2,{id:"call-1",children:"Call"}),"\n",(0,n.jsx)(l.p,{children:"Extends Expr instanceof CallImpl"}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getargumentint-n",children:"getArgument(int n)"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getanargument",children:"getAnArgument()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getkeywordargumentstring-keyword",children:"getKeywordArgument(string keyword)"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getnumberofarguments",children:"getNumberOfArguments()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getatarget",children:"getATarget()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getachildstring-pred",children:"getAChild(string pred)"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string getAPrimaryQlClass() { result = "Call" }\n'})}),"\n",(0,n.jsx)(l.p,{children:"Returns the kind of the class."}),"\n",(0,n.jsx)(l.h3,{id:"getargumentint-n",children:"getArgument(int n)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getArgument(int n) { result = super.getArgumentImpl(n) }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the ",(0,n.jsx)(l.code,{children:"n"}),"th argument of this method call. For instance,"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"foo(0, bar: 1)\nyield 0, bar: 1\n"})}),"\n",(0,n.jsxs)(l.p,{children:["For ",(0,n.jsx)(l.code,{children:"getArgument(0)"})," the result is the ",(0,n.jsx)(l.code,{children:"IntegerLiteral"})," 0. While for ",(0,n.jsx)(l.code,{children:"getArgument(1)"})," the result is a ",(0,n.jsx)(l.code,{children:"Pair"}),"."]}),"\n",(0,n.jsx)(l.h3,{id:"getanargument",children:"getAnArgument()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getAnArgument() { result = this.getArgument(_) }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets an argument of this method call."}),"\n",(0,n.jsx)(l.h3,{id:"getkeywordargumentstring-keyword",children:"getKeywordArgument(string keyword)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getKeywordArgument(string keyword) {\n exists(Pair p |\n p = this.getAnArgument() and\n p.getKey().getConstantValue().isSymbol(keyword) and\n result = p.getValue()\n )\n }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the value of the keyword argument whose key is ",(0,n.jsx)(l.code,{children:"keyword"}),", if any."]}),"\n",(0,n.jsxs)(l.p,{children:["For example, the result for ",(0,n.jsx)(l.code,{children:'getKeywordArgument("qux")'})," in the following example is the ",(0,n.jsx)(l.code,{children:"IntegerLiteral"})," 123."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:'foo :bar "baz", qux: 123\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getnumberofarguments",children:"getNumberOfArguments()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final int getNumberOfArguments() { result = super.getNumberOfArgumentsImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the number of arguments of this method call."}),"\n",(0,n.jsx)(l.h3,{id:"getatarget",children:"getATarget()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Callable getATarget() {\n exists(DataFlowCall c |\n this = c.asCall().getExpr() and\n TCfgScope(result) = viableCallableLambda(c, _)\n )\n or\n result = getTarget(TNormalCall(this.getAControlFlowNode()))\n }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets a potential target of this call, if any."}),"\n",(0,n.jsx)(l.h3,{id:"getachildstring-pred",children:"getAChild(string pred)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override AstNode getAChild(string pred) {\n result = Expr.super.getAChild(pred)\n or\n pred = "getArgument" and result = this.getArgument(_)\n}\n\n'})}),"\n",(0,n.jsx)(l.p,{children:"Gets a child of the predicate passed by argument."}),"\n",(0,n.jsx)(l.h2,{id:"methodcall",children:"MethodCall"}),"\n",(0,n.jsx)(l.p,{children:"A method call."}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-1",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getreceiver",children:"getReceiver()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getmethodname",children:"getMethodName()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getblock",children:"getBlock()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getblockargument",children:"getBlockArgument()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#hasblock",children:"hasBlock()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#issafenavigation",children:"isSafeNavigation()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring",children:"toString()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getachildstring-pred-1",children:"getAChild(string pred)"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-1",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string getAPrimaryQlClass() { result = "MethodCall" }\n'})}),"\n",(0,n.jsx)(l.p,{children:"Returns the kind of the class."}),"\n",(0,n.jsx)(l.h3,{id:"getreceiver",children:"getReceiver()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getReceiver() { result = super.getReceiverImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the receiver of this call, if any. For example:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.bar\nBaz::qux\ncorge()\n"})}),"\n",(0,n.jsxs)(l.p,{children:["The result for the call to ",(0,n.jsx)(l.code,{children:"bar"})," is the ",(0,n.jsx)(l.code,{children:"Expr"})," for ",(0,n.jsx)(l.code,{children:"foo"}),"; the result for the call to ",(0,n.jsx)(l.code,{children:"qux"})," is the ",(0,n.jsx)(l.code,{children:"Expr"})," for ",(0,n.jsx)(l.code,{children:"Baz"}),"; for the call to ",(0,n.jsx)(l.code,{children:"corge"})," there is no result."]}),"\n",(0,n.jsx)(l.h3,{id:"getmethodname",children:"getMethodName()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final string getMethodName() { result = super.getMethodNameImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the name of the method being called. For example, in:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.bar x, y\n"})}),"\n",(0,n.jsxs)(l.p,{children:["The result is ",(0,n.jsx)(l.code,{children:'"bar"'}),". Super calls call a method with the same name as the current method, so the result for a super call is the name of the current method."]}),"\n",(0,n.jsx)(l.p,{children:"E.g:"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:'def foo\n super # the result for this super call is "foo"\nend\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getblock",children:"getBlock()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Block getBlock() { result = super.getBlockImpl() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the block of this method call, if any."}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.each { |x| puts x }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getblockargument",children:"getBlockArgument()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final BlockArgument getBlockArgument() { result = this.getAnArgument() }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Gets the block argument of this method call, if any."}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo(&block)\n"})}),"\n",(0,n.jsx)(l.h3,{id:"hasblock",children:"hasBlock()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final predicate hasBlock() { exists(this.getBlock()) or exists(this.getBlockArgument()) }\n"})}),"\n",(0,n.jsx)(l.p,{children:"Holds if this method call has a block or block argument."}),"\n",(0,n.jsx)(l.h3,{id:"issafenavigation",children:"isSafeNavigation()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final predicate isSafeNavigation() { super.isSafeNavigationImpl() }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Holds if the safe navigation operator (",(0,n.jsx)(l.code,{children:"&."}),") is used in this call."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo&.empty?\n"})}),"\n",(0,n.jsx)(l.h3,{id:"tostring",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string toString() { result = "call to " + this.getMethodName() }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getachildstring-pred-1",children:"getAChild(string pred)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override AstNode getAChild(string pred) {\n result = Call.super.getAChild(pred)\n or\n pred = "getReceiver" and result = this.getReceiver()\n or\n pred = "getBlock" and result = this.getBlock()\n }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"unknownmethodcall",children:"UnknownMethodCall"}),"\n",(0,n.jsx)(l.p,{children:"Extends MethodCall"}),"\n",(0,n.jsxs)(l.p,{children:["A ",(0,n.jsx)(l.code,{children:"Method"})," call that has no known target. These will typically be calls to methods inherited from a superclass."]}),"\n",(0,n.jsxs)(l.p,{children:["Diclaimer: When API Graphs is able to resolve calls to methods like ",(0,n.jsx)(l.code,{children:"Kernel.send"})," this class is no longer necessary and should be removed."]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#unknownmethodcall-1",children:"UnknownMethodCall"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"unknownmethodcall-1",children:"UnknownMethodCall"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"UnknownMethodCall() { not exists(this.(Call).getATarget()) }\n"})}),"\n",(0,n.jsx)(l.h2,{id:"settermethodcall",children:"SetterMethodCall"}),"\n",(0,n.jsxs)(l.p,{children:["A call to a setter method. This class extends ",(0,n.jsx)(l.code,{children:"MethodCall"})," and ",(0,n.jsx)(l.code,{children:"TMethodCallSynth"}),"."]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#settermethodcall",children:"SetterMethodCall"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-2",children:"getAPrimaryQlClass"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#gettargetname",children:"getTargetName()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"settermethodcall-1",children:"SetterMethodCall()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"SetterMethodCall() { this = TMethodCallSynth(_, _, _, true, _) }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-2",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "SetterMethodCall" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"gettargetname",children:"getTargetName()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final string getTargetName() {\n exists(string methodName |\n methodName = this.getMethodName() and\n result = methodName.prefix(methodName.length() - 1)\n )\n }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the name of the method being called without the trailing ",(0,n.jsx)(l.code,{children:"="}),". For example, in the following two statements the target name is ",(0,n.jsx)(l.code,{children:"value"}),":"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo.value=(1)\nfoo.value = 1\n"})}),"\n",(0,n.jsx)(l.h2,{id:"elementreference",children:"ElementReference"}),"\n",(0,n.jsxs)(l.p,{children:["An element reference; a call to the ",(0,n.jsx)(l.code,{children:"[]"})," method."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"a[0]\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Extends ",(0,n.jsx)(l.code,{children:"MethodCall"})]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-3",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-1",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-3",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "ElementReference" }\n'})}),"\n",(0,n.jsx)(l.p,{children:"Returns the kind of the class."}),"\n",(0,n.jsx)(l.h3,{id:"tostring-1",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "...[...]" }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"yieldcall",children:"YieldCall"}),"\n",(0,n.jsxs)(l.p,{children:["A call to yield. Extends ",(0,n.jsx)(l.code,{children:"Call"})," class."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"yield x, y\n"})}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-4",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-2",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-4",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "YieldCall" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-2",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "yield ..." }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"supercall",children:"SuperCall"}),"\n",(0,n.jsxs)(l.p,{children:["A call to ",(0,n.jsx)(l.code,{children:"super"}),"."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"class Foo < Bar\n def baz\n super\n end\nend\n"})}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-5",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-3",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-5",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "SuperCall" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-3",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'override string toString() { result = "super call to " + this.getMethodName() }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"blockargument",children:"BlockArgument"}),"\n",(0,n.jsxs)(l.p,{children:["A block argument in a method call. It extends ",(0,n.jsx)(l.code,{children:"Expr"})]}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#blockargument-1",children:"BlockArgument()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-6",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getvalue",children:"getValue()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-4",children:"toString()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getachildstring-pred-2",children:"getAChild()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"blockargument-1",children:"BlockArgument()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"BlockArgument() { this = TBlockArgument(g) }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-6",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "BlockArgument" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getvalue",children:"getValue()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"final Expr getValue() {\n toGenerated(result) = g.getChild() or\n synthChild(this, 0, result)\n }\n"})}),"\n",(0,n.jsxs)(l.p,{children:["Gets the underlying expression representing the block. In the following example, the result is the ",(0,n.jsx)(l.code,{children:"Expr"})," for ",(0,n.jsx)(l.code,{children:"bar"}),":"]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo(&bar)\n"})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-4",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "&..." }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"getachildstring-pred-2",children:"getAChild(string pred)"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override AstNode getAChild(string pred) {\n result = super.getAChild(pred)\n or\n pred = "getValue" and result = this.getValue()\n }\n'})}),"\n",(0,n.jsx)(l.h2,{id:"forwardedarguments",children:"ForwardedArguments"}),"\n",(0,n.jsxs)(l.p,{children:["A ",(0,n.jsx)(l.code,{children:"..."})," expression that contains forwarded arguments. This class extends ",(0,n.jsx)(l.code,{children:"Expr"}),"."]}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{className:"language-rb",children:"foo(...)\n"})}),"\n",(0,n.jsxs)(l.ul,{children:["\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#forwardedarguments-1",children:"ForwardedArguments()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#getaprimaryqlclass-7",children:"getAPrimaryQlClass()"})}),"\n",(0,n.jsx)(l.li,{children:(0,n.jsx)(l.a,{href:"#tostring-5",children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(l.h3,{id:"forwardedarguments-1",children:"ForwardedArguments()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:"ForwardedArguments() { this = TForwardArgument(g) }\n"})}),"\n",(0,n.jsx)(l.h3,{id:"getaprimaryqlclass-7",children:"getAPrimaryQlClass()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string getAPrimaryQlClass() { result = "ForwardedArguments" }\n'})}),"\n",(0,n.jsx)(l.h3,{id:"tostring-5",children:"toString()"}),"\n",(0,n.jsx)(l.pre,{children:(0,n.jsx)(l.code,{children:'final override string toString() { result = "..." }\n'})}),"\n",(0,n.jsxs)(l.p,{children:["A ",(0,n.jsx)(l.code,{children:"..."})," expression that contains forwarded arguments."]})]})}function o(e={}){const{wrapper:l}={...(0,s.R)(),...e.components};return l?(0,n.jsx)(l,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1503:(e,l,r)=>{r.d(l,{R:()=>i,x:()=>d});var n=r(758);const s={},t=n.createContext(s);function i(e){const l=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(l):{...l,...e}}),[l,e])}function d(e){let l;return l=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(t.Provider,{value:l},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9cb5c5d3.ca3a9d87.js b/assets/js/9cb5c5d3.ca3a9d87.js new file mode 100644 index 0000000..fcccd55 --- /dev/null +++ b/assets/js/9cb5c5d3.ca3a9d87.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[891],{1465:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"Classes","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Access","href":"/CyScout/docs/Classes/Access","docId":"Classes/Access","unlisted":false},{"type":"link","label":"BasicBlock","href":"/CyScout/docs/Classes/BasicBlock","docId":"Classes/BasicBlock","unlisted":false},{"type":"link","label":"Block Statement","href":"/CyScout/docs/Classes/Block","docId":"Classes/Block","unlisted":false},{"type":"link","label":"Call","href":"/CyScout/docs/Classes/Call","docId":"Classes/Call","unlisted":false},{"type":"link","label":"Control Flow Graph","href":"/CyScout/docs/Classes/ControlFlowGraph","docId":"Classes/ControlFlowGraph","unlisted":false},{"type":"link","label":"Enclosing","href":"/CyScout/docs/Classes/Enclosing","docId":"Classes/Enclosing","unlisted":false},{"type":"link","label":"Function","href":"/CyScout/docs/Classes/Function","docId":"Classes/Function","unlisted":false},{"type":"link","label":"Specifier","href":"/CyScout/docs/Classes/Specifier","docId":"Classes/Specifier","unlisted":false},{"type":"link","label":"SubBasicBlock","href":"/CyScout/docs/Classes/SubBasicBlock","docId":"Classes/SubBasicBlock","unlisted":false},{"type":"link","label":"Variable","href":"/CyScout/docs/Classes/Variable","docId":"Classes/Variable","unlisted":false},{"type":"link","label":"Index","href":"/CyScout/docs/Classes/classesIndex","docId":"Classes/classesIndex","unlisted":false}]},{"type":"category","label":"Detectors Index","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Divide before multiply","href":"/CyScout/docs/Detectors/divide-before-multiply","docId":"Detectors/divide-before-multiply","unlisted":false},{"type":"link","label":"Incorrect exponentiation","href":"/CyScout/docs/Detectors/incorrect-exp","docId":"Detectors/incorrect-exp","unlisted":false},{"type":"link","label":"incorrect-shift","href":"/CyScout/docs/Detectors/incorrect-shift","docId":"Detectors/incorrect-shift","unlisted":false},{"type":"link","label":"is-unreachable","href":"/CyScout/docs/Detectors/is-unreachable","docId":"Detectors/is-unreachable","unlisted":false},{"type":"link","label":"msg-value-in-for-loop","href":"/CyScout/docs/Detectors/msg-value-in-for-loop","docId":"Detectors/msg-value-in-for-loop","unlisted":false},{"type":"link","label":"transfer-from","href":"/CyScout/docs/Detectors/transfer-from","docId":"Detectors/transfer-from","unlisted":false},{"type":"link","label":"Unchecked Send","href":"/CyScout/docs/Detectors/unchecked-send","docId":"Detectors/unchecked-send","unlisted":false},{"type":"link","label":"Unrpotected self destruct","href":"/CyScout/docs/Detectors/unprotected-self-destruct","docId":"Detectors/unprotected-self-destruct","unlisted":false}],"href":"/CyScout/docs/Detectors/"},{"type":"category","label":"CyScout","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"det01_doc","href":"/CyScout/docs/README/det01_doc","docId":"README/det01_doc","unlisted":false},{"type":"link","label":"det02_doc","href":"/CyScout/docs/README/det02_doc","docId":"README/det02_doc","unlisted":false},{"type":"link","label":"det03_doc","href":"/CyScout/docs/README/det03_doc","docId":"README/det03_doc","unlisted":false},{"type":"link","label":"det04_doc","href":"/CyScout/docs/README/det04_doc","docId":"README/det04_doc","unlisted":false}],"href":"/CyScout/docs/README/"}]},"docs":{"Classes/Access":{"id":"Classes/Access","title":"Access","description":"Classes","sidebar":"tutorialSidebar"},"Classes/BasicBlock":{"id":"Classes/BasicBlock","title":"BasicBlock","description":"Provides a library for reasoning about control flow at the granularity of basic blocks. This is usually much more efficient than reasoning directly at the level of ControlFlowNodes.","sidebar":"tutorialSidebar"},"Classes/Block":{"id":"Classes/Block","title":"Block Statement","description":"Implements a class to model a solidity block statement","sidebar":"tutorialSidebar"},"Classes/Call":{"id":"Classes/Call","title":"Call","description":"Classes","sidebar":"tutorialSidebar"},"Classes/classesIndex":{"id":"Classes/classesIndex","title":"Index","description":"- Access","sidebar":"tutorialSidebar"},"Classes/ControlFlowGraph":{"id":"Classes/ControlFlowGraph","title":"Control Flow Graph","description":"In this module there is","sidebar":"tutorialSidebar"},"Classes/Enclosing":{"id":"Classes/Enclosing","title":"Enclosing","description":"Provides predicates for finding the smallest element that encloses an expression or statement.","sidebar":"tutorialSidebar"},"Classes/Function":{"id":"Classes/Function","title":"Function","description":"Methods","sidebar":"tutorialSidebar"},"Classes/Specifier":{"id":"Classes/Specifier","title":"Specifier","description":"Provides classes for modeling specifiers and attributes.","sidebar":"tutorialSidebar"},"Classes/SubBasicBlock":{"id":"Classes/SubBasicBlock","title":"SubBasicBlock","description":"Provides the SubBasicBlock class, used for partitioning basic blocks in smaller pieces.","sidebar":"tutorialSidebar"},"Classes/Variable":{"id":"Classes/Variable","title":"Variable","description":"Classes","sidebar":"tutorialSidebar"},"Detectors/divide-before-multiply":{"id":"Detectors/divide-before-multiply","title":"Divide before multiply","description":"Description","sidebar":"tutorialSidebar"},"Detectors/incorrect-exp":{"id":"Detectors/incorrect-exp","title":"Incorrect exponentiation","description":"Description","sidebar":"tutorialSidebar"},"Detectors/incorrect-shift":{"id":"Detectors/incorrect-shift","title":"incorrect-shift","description":"Incorrect shift in assembly","sidebar":"tutorialSidebar"},"Detectors/index":{"id":"Detectors/index","title":"Detectors Index","description":"- deadCode","sidebar":"tutorialSidebar"},"Detectors/is-unreachable":{"id":"Detectors/is-unreachable","title":"is-unreachable","description":"Is unreachable","sidebar":"tutorialSidebar"},"Detectors/msg-value-in-for-loop":{"id":"Detectors/msg-value-in-for-loop","title":"msg-value-in-for-loop","description":"msg.value in for loops","sidebar":"tutorialSidebar"},"Detectors/transfer-from":{"id":"Detectors/transfer-from","title":"transfer-from","description":"transfer-from uses arbitrary from","sidebar":"tutorialSidebar"},"Detectors/unchecked-send":{"id":"Detectors/unchecked-send","title":"Unchecked Send","description":"Description","sidebar":"tutorialSidebar"},"Detectors/unprotected-self-destruct":{"id":"Detectors/unprotected-self-destruct","title":"Unrpotected self destruct","description":"Description","sidebar":"tutorialSidebar"},"README/det01_doc":{"id":"README/det01_doc","title":"det01_doc","description":"transferFrom uses arbitrary from","sidebar":"tutorialSidebar"},"README/det02_doc":{"id":"README/det02_doc","title":"det02_doc","description":"\'FIX\' word in comments","sidebar":"tutorialSidebar"},"README/det03_doc":{"id":"README/det03_doc","title":"det03_doc","description":"Incorrect shift in assembly","sidebar":"tutorialSidebar"},"README/det04_doc":{"id":"README/det04_doc","title":"det04_doc","description":"Dead code","sidebar":"tutorialSidebar"},"README/readme":{"id":"README/readme","title":"CyScout","description":"Run queries and detect vulnerabilities in your smart contracts using CodeQL-Solidity","sidebar":"tutorialSidebar"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/aa80dae2.7ebf045e.js b/assets/js/aa80dae2.7ebf045e.js new file mode 100644 index 0000000..0cc59ee --- /dev/null +++ b/assets/js/aa80dae2.7ebf045e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[309],{6575:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>t,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var c=i(6070),s=i(1503);const o={},l="BasicBlock",r={id:"Classes/BasicBlock",title:"BasicBlock",description:"Provides a library for reasoning about control flow at the granularity of basic blocks. This is usually much more efficient than reasoning directly at the level of ControlFlowNodes.",source:"@site/docs/Classes/BasicBlock.md",sourceDirName:"Classes",slug:"/Classes/BasicBlock",permalink:"/CyScout/docs/Classes/BasicBlock",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/BasicBlock.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Access",permalink:"/CyScout/docs/Classes/Access"},next:{title:"Block Statement",permalink:"/CyScout/docs/Classes/Block"}},t={},d=[{value:"Module, Classes and Predicate",id:"module-classes-and-predicate",level:2},{value:"Cached",id:"cached",level:2},{value:"Predicates",id:"predicates",level:3},{value:"basic_block_entry_node(ControlFlowNode node)",id:"basic_block_entry_nodecontrolflownode-node",level:3},{value:"non_primitive_basic_block_entry_node(ControlFlowNode node",id:"non_primitive_basic_block_entry_nodecontrolflownode-node",level:3},{value:"equalsPrimitiveBasicBlock(BasicBlock bb)",id:"equalsprimitivebasicblockbasicblock-bb",level:3},{value:"basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)",id:"basic_block_membercontrolflownode-node-basicblock-bb-int-pos",level:3},{value:"predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)",id:"predicate-non_primitive_basic_block_membercontrolflownode-node-basicblock-bb-int-pos",level:3},{value:"bb_length(BasicBlock bb)",id:"bb_lengthbasicblock-bb",level:3},{value:"bb_successor_cached(BasicBlock pred, BasicBlock succ)",id:"bb_successor_cachedbasicblock-pred-basicblock-succ",level:3},{value:"BasicBlock",id:"basicblock-1",level:2},{value:"Methods and predicates",id:"methods-and-predicates",level:3},{value:"BasicBlock()",id:"basicblock-2",level:3},{value:"contains(ControlFlowNode node)",id:"containscontrolflownode-node",level:3},{value:"getNode(int pos)",id:"getnodeint-pos",level:3},{value:"getANode()",id:"getanode",level:3},{value:"getASuccessor()",id:"getasuccessor",level:3},{value:"getAPredecessor()",id:"getapredecessor",level:3},{value:"getATrueSuccessor()",id:"getatruesuccessor",level:3},{value:"getAFalseSuccessor()",id:"getafalsesuccessor",level:3},{value:"getEnd()",id:"getend",level:3},{value:"getStart()",id:"getstart",level:3},{value:"length()",id:"length",level:3},{value:"hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn)",id:"haslocationinfostring-filepath-int-startline-int-startcolumn-int-endline-int-endcolumn",level:3},{value:"hasLocationInfoInternal(string file, int line, int col, string endf, int endl, int endc)",id:"haslocationinfointernalstring-file-int-line-int-col-string-endf-int-endl-int-endc",level:3},{value:"getEnclosingFunction()",id:"getenclosingfunction",level:3},{value:"inLoop()",id:"inloop",level:3},{value:"isReachable()",id:"isreachable",level:3},{value:"isUnreachable()",id:"isunreachable",level:3},{value:"EntryBasicBlock",id:"entrybasicblock",level:2},{value:"EntryBasicBlock()",id:"entrybasicblock-1",level:3},{value:"ExitBasicBlock",id:"exitbasicblock",level:2},{value:"ExitBasicBlock(",id:"exitbasicblock-1",level:3},{value:"unreachable(ControlFlowNode n)",id:"unreachablecontrolflownode-n",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"basicblock",children:"BasicBlock"})}),"\n",(0,c.jsxs)(n.p,{children:["Provides a library for reasoning about control flow at the granularity of basic blocks. This is usually much more efficient than reasoning directly at the level of ",(0,c.jsx)(n.code,{children:"ControlFlowNode"}),"s."]}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"BasicBlock"}),"s are refinements of ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s, taking\nimpossible CFG edges into account (using the ",(0,c.jsx)(n.code,{children:"successors_adapted"}),"\nrelation). The refinement manifests itself in two changes:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["The successor relation on ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s uses ",(0,c.jsx)(n.code,{children:"successors_adapted"}),"\n(instead of ",(0,c.jsx)(n.code,{children:"successors_extended"})," used by ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s). Consequently, some edges between ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s may be removed. Example:"]}),"\n"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"x = 1; // s1\nif (true) { // s2\n x = 2; // s3\n} else {\n x = 3; // s4\n}\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"BasicBlock"})," successor edge from the basic block containing ",(0,c.jsx)(n.code,{children:"s1"})," and ",(0,c.jsx)(n.code,{children:"s2"})," to the basic block containing ",(0,c.jsx)(n.code,{children:"s4"})," is removed."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s may be split up into two or more\n",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s: Internal nodes of ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s whose\npredecessor edges have been removed (unreachable code) will be entry points of new ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s. Consequently, each entry point of a ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"})," will also be an entry point of a ",(0,c.jsx)(n.code,{children:"BasicBlock"}),", but the converse does not necessarily hold. Example:"]}),"\n"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"x = 1; // s5\nabort(); // s6\nx = 2; // s7\n"})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"s5"}),"-",(0,c.jsx)(n.code,{children:"s7"})," belong to the same ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),", but the CFG edge from ",(0,c.jsx)(n.code,{children:"s6"})," to ",(0,c.jsx)(n.code,{children:"s7"})," is impossible, so ",(0,c.jsx)(n.code,{children:"s7"})," will be the entry point of its own (unreachable) ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["Note that, although possible, two or more ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s are never merged to one ",(0,c.jsx)(n.code,{children:"BasicBlock"}),": Consider the first example above; it would be possible to define a single ",(0,c.jsx)(n.code,{children:"BasicBlock"})," consisting of ",(0,c.jsx)(n.code,{children:"s1"}),"-",(0,c.jsx)(n.code,{children:"s3"}),", however, the result would be counter-intuitive."]}),"\n",(0,c.jsx)(n.h2,{id:"module-classes-and-predicate",children:"Module, Classes and Predicate"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#cached",children:"Cached"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basicblock-1",children:"BasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#entrybasicblock",children:"EntryBasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#exitbasicblock",children:"ExitBasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#unreachablecontrolflownode-n",children:"unreachable(ControlFlowNode n)"})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"cached",children:"Cached"}),"\n",(0,c.jsx)(n.h3,{id:"predicates",children:"Predicates"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basic_block_entry_nodecontrolflownode-node",children:"basic_block_entry_node(ControlFlowNode node)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#non_primitive_basic_block_entry_nodecontrolflownode-node",children:"non_primitive_basic_block_entry_node(ControlFlowNode node)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#equalsprimitivebasicblockbasicblock-bb",children:"equalsPrimitiveBasicBlock(BasicBlock bb)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basic_block_membercontrolflownode-node-basicblock-bb-int-pos",children:"basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#non_primitive_basic_block_entry_nodecontrolflownode-node",children:"non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#bb_lengthbasicblock-bb",children:"bb_length(BasicBlock bb)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#bb_successor_cachedbasicblock-pred-basicblock-succ",children:"bb_successor_cached(BasicBlock pred, BasicBlock succ)"})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"basic_block_entry_nodecontrolflownode-node",children:"basic_block_entry_node(ControlFlowNode node)"}),"\n",(0,c.jsxs)(n.p,{children:["Any node that is the entry point of a primitive basic block is\nalso the entry point of a basic block. In addition, all nodes\nwith a primitive successor, where the predecessor has been pruned\n(that is, ",(0,c.jsx)(n.code,{children:"getAPredecessor()"})," does not exist while a predecessor\nusing the primitive ",(0,c.jsx)(n.code,{children:"successors_extended"})," relation does exist), is also considered a basic block entry node."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate basic_block_entry_node(ControlFlowNode node) {\n primitive_basic_block_entry_node(node) or\n non_primitive_basic_block_entry_node(node)\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"non_primitive_basic_block_entry_nodecontrolflownode-node",children:"non_primitive_basic_block_entry_node(ControlFlowNode node"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"private predicate non_primitive_basic_block_entry_node(ControlFlowNode node) {\n not primitive_basic_block_entry_node(node) and\n not exists(node.getAPredecessor()) and\n successors_extended(node, _)\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"equalsprimitivebasicblockbasicblock-bb",children:"equalsPrimitiveBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if basic block ",(0,c.jsx)(n.code,{children:"bb"})," equals a primitive basic block."]}),"\n",(0,c.jsx)(n.p,{children:"There are two situations in which this isnot* the case:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["Either the entry node of ",(0,c.jsx)(n.code,{children:"bb"})," does not correspond to an\nentry node of a primitive basic block, or"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"The primitive basic block with the same entry node contains\na (non-entry) node which is the entry node of a non-primitive\nbasic block (that is, the primitive basic block has been split\nup)."}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This predicate is used for performance optimization only:\nWhenever a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," equals a ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),", we can\nreuse predicates already computed for ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlocks"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"private predicate equalsPrimitiveBasicBlock(BasicBlock bb) {\n primitive_basic_block_entry_node(bb) and\n not exists(int i |\n i > 0 and\n non_primitive_basic_block_entry_node(bb.(PrimitiveBasicBlock).getNode(i))\n )\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"basic_block_membercontrolflownode-node-basicblock-bb-int-pos",children:"basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if ",(0,c.jsx)(n.code,{children:"node"})," is the ",(0,c.jsx)(n.code,{children:"pos"}),"th control-flow node in basic block ",(0,c.jsx)(n.code,{children:"bb"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"cached predicate basic_block_member(ControlFlowNode node, BasicBlock bb, int pos) {\n equalsPrimitiveBasicBlock(bb) and primitive_basic_block_member(node, bb, pos) // reuse already computed relation\n or\n non_primitive_basic_block_member(node, bb, pos)\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"predicate-non_primitive_basic_block_membercontrolflownode-node-basicblock-bb-int-pos",children:"predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"private predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos) {\n not equalsPrimitiveBasicBlock(bb) and node = bb and pos = 0\n or\n not node instanceof BasicBlock and\n exists(ControlFlowNode pred | successors_extended(pred, node) |\n non_primitive_basic_block_member(pred, bb, pos - 1)\n )\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"bb_lengthbasicblock-bb",children:"bb_length(BasicBlock bb)"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the number of control-flow nodes in the basic block ",(0,c.jsx)(n.code,{children:"bb"}),"./"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"cached int bb_length(BasicBlock bb) {\n if equalsPrimitiveBasicBlock(bb)\n then result = bb.(PrimitiveBasicBlock).length() // reuse already computed relation\n else result = strictcount(ControlFlowNode node | basic_block_member(node, bb, _))\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"bb_successor_cachedbasicblock-pred-basicblock-succ",children:"bb_successor_cached(BasicBlock pred, BasicBlock succ)"}),"\n",(0,c.jsx)(n.p,{children:"Successor relation for basic blocks."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"cached predicate bb_successor_cached(BasicBlock pred, BasicBlock succ) {\n exists(ControlFlowNode last |\n basic_block_member(last, pred, bb_length(pred) - 1) and\n last.getASuccessor() = succ\n )\n}\n"})}),"\n",(0,c.jsx)(n.h2,{id:"basicblock-1",children:"BasicBlock"}),"\n",(0,c.jsx)(n.p,{children:"A basic block in the Solidity control-flow graph."}),"\n",(0,c.jsx)(n.p,{children:"A basic block is a simple sequence of control-flow nodes,\nconnected to each other and nothing else:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:" A - B - C - D ABCD is a basic block\n"})}),"\n",(0,c.jsx)(n.p,{children:"Any incoming or outgoing edges break the block into two:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:" A - B > C - D AB is a basic block and CD is a basic block (C has two incoming edges)\n\n\n A - B < C - D AB is a basic block and CD is a basic block (B has two outgoing edges)\n"})}),"\n",(0,c.jsx)(n.h3,{id:"methods-and-predicates",children:"Methods and predicates"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basicblock-2",children:"BasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#containscontrolflownode-node",children:"contains"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getnodeint-pos",children:"getNode"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getanode",children:"getANode"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getasuccessor",children:"getASuccessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getapredecessor",children:"getAPredecessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getatruesuccessor",children:"getATrueSuccessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getafalsesuccessor",children:"getAFalseSuccessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getend",children:"getEnd"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getstart",children:"getStart"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#length",children:"length"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#haslocationinfostring-filepath-int-startline-int-startcolumn-int-endline-int-endcolumn",children:"hasLocationInfo"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#haslocationinfointernalstring-file-int-line-int-col-string-endf-int-endl-int-endc",children:"hasLocationInfoInternal"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getenclosingfunction",children:"getEnclosingFunction"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#inloop",children:"inLoop"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#isreachable",children:"isReachable"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#isunreachable",children:"isUnreachable"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#unreachablecontrolflownode-n",children:"unreachable"})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"basicblock-2",children:"BasicBlock()"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock() { basic_block_entry_node(this) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"containscontrolflownode-node",children:"contains(ControlFlowNode node)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if this basic block contains ",(0,c.jsx)(n.code,{children:"node"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate contains(ControlFlowNode node) { basic_block_member(node, this, _) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getnodeint-pos",children:"getNode(int pos)"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," at position ",(0,c.jsx)(n.code,{children:"pos"})," in this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getNode(int pos) { basic_block_member(result, this, pos) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getanode",children:"getANode()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," in this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getANode() { basic_block_member(result, this, _) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getasuccessor",children:"getASuccessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," that is a direct successor of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getASuccessor() { bb_successor(this, result) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getapredecessor",children:"getAPredecessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," that is a direct predecessor of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getAPredecessor() { bb_successor(result, this) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getatruesuccessor",children:"getATrueSuccessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," such that the control-flow edge ",(0,c.jsx)(n.code,{children:"(this, result)"})," may be taken when the outgoing edge of this basic block is an expression that is true."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getATrueSuccessor() { result.getStart() = this.getEnd().getATrueSuccessor() }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getafalsesuccessor",children:"getAFalseSuccessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," such that the control-flow edge ",(0,c.jsx)(n.code,{children:"(this, result)"})," may be taken when the outgoing edge of this basic block is an expression that is false."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getAFalseSuccessor() { result.getStart() = this.getEnd().getAFalseSuccessor() }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getend",children:"getEnd()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the final ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getEnd() { basic_block_member(result, this, bb_length(this) - 1) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getstart",children:"getStart()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the first ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getStart() { result = this }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"length",children:"length()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the number of ",(0,c.jsx)(n.code,{children:"ControlFlowNode"}),"s in this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"int length() { result = bb_length(this) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"haslocationinfostring-filepath-int-startline-int-startcolumn-int-endline-int-endcolumn",children:"hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if this element is at the specified location.\nThe location spans column ",(0,c.jsx)(n.code,{children:"startcolumn"})," of line ",(0,c.jsx)(n.code,{children:"startline"})," to column ",(0,c.jsx)(n.code,{children:"endcolumn"})," of line ",(0,c.jsx)(n.code,{children:"endline"})," in file ",(0,c.jsx)(n.code,{children:"filepath"}),". For more information, see\n",(0,c.jsx)(n.a,{href:"https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/",children:"Locations"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"Yields no result if this basic block spans multiple source files."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate hasLocationInfo(\n string filepath, int startline, int startcolumn, int endline, int endcolumn\n ) {\n this.hasLocationInfoInternal(filepath, startline, startcolumn, filepath, endline, endcolumn)\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"haslocationinfointernalstring-file-int-line-int-col-string-endf-int-endl-int-endc",children:"hasLocationInfoInternal(string file, int line, int col, string endf, int endl, int endc)"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:" pragma[noinline]\n private predicate hasLocationInfoInternal(\n string file, int line, int col, string endf, int endl, int endc\n ) {\n this.getStart().getLocation().hasLocationInfo(file, line, col, _, _) and\n this.getEnd().getLocation().hasLocationInfo(endf, _, _, endl, endc)\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getenclosingfunction",children:"getEnclosingFunction()"}),"\n",(0,c.jsx)(n.p,{children:"Gets the function containing this basic block."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"Solidity::FunctionDefinition getEnclosingFunction() { result = this.getStart().getControlFlowScope() }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"inloop",children:"inLoop()"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if this basic block is in a loop of the control-flow graph. This includes loops created by ",(0,c.jsx)(n.code,{children:"goto"})," statements. This predicate may not hold\neven if this basic block is syntactically inside a ",(0,c.jsx)(n.code,{children:"while"})," loop if the necessary back edges are unreachable."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate inLoop() { this.getASuccessor+() = this }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"isreachable",children:"isReachable()"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if control flow may reach this basic block from a function entry point or any handler of a reachable ",(0,c.jsx)(n.code,{children:"try"})," statement."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate isReachable() {\n \n exists(Solidity::FunctionDefinition f | f.getBody() = this)\n or\n exists(BasicBlock pred | pred.getASuccessor() = this and pred.isReachable())\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"isunreachable",children:"isUnreachable()"}),"\n",(0,c.jsxs)(n.p,{children:["Means ",(0,c.jsx)(n.code,{children:"not isReachable()"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate isUnreachable() { not this.isReachable() }\n"})}),"\n",(0,c.jsx)(n.h2,{id:"entrybasicblock",children:"EntryBasicBlock"}),"\n",(0,c.jsx)(n.p,{children:"An entry point of a function."}),"\n",(0,c.jsx)(n.h3,{id:"entrybasicblock-1",children:"EntryBasicBlock()"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"EntryBasicBlock() { exists(Solidity::FunctionDefinition f | this = f.getBody()) }\n"})}),"\n",(0,c.jsx)(n.h2,{id:"exitbasicblock",children:"ExitBasicBlock"}),"\n",(0,c.jsx)(n.p,{children:"A basic block whose last node is the exit point of a function."}),"\n",(0,c.jsx)(n.h3,{id:"exitbasicblock-1",children:"ExitBasicBlock("}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ExitBasicBlock() {\n this.getEnd() instanceof Solidity::FunctionBody \n // or\n // aborting(this.getEnd())\n}\n"})}),"\n",(0,c.jsx)(n.h2,{id:"unreachablecontrolflownode-n",children:"unreachable(ControlFlowNode n)"}),"\n",(0,c.jsx)(n.p,{children:"Correct relation for reachability of ControlFlowNodes."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate unreachable(ControlFlowNode n) {\n exists(BasicBlock bb | bb.contains(n) and bb.isUnreachable())\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(a,{...e})}):a(e)}},1503:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>r});var c=i(758);const s={},o=c.createContext(s);function l(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aa80dae2.b5140f84.js b/assets/js/aa80dae2.b5140f84.js deleted file mode 100644 index b9e62a4..0000000 --- a/assets/js/aa80dae2.b5140f84.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[309],{6575:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>t,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var c=i(6070),s=i(1503);const o={},l="BasicBlock",r={id:"Classes/BasicBlock",title:"BasicBlock",description:"Provides a library for reasoning about control flow at the granularity of basic blocks. This is usually much more efficient than reasoning directly at the level of ControlFlowNodes.",source:"@site/docs/Classes/BasicBlock.md",sourceDirName:"Classes",slug:"/Classes/BasicBlock",permalink:"/docs/Classes/BasicBlock",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/BasicBlock.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Access",permalink:"/docs/Classes/Access"},next:{title:"Block Statement",permalink:"/docs/Classes/Block"}},t={},d=[{value:"Module, Classes and Predicate",id:"module-classes-and-predicate",level:2},{value:"Cached",id:"cached",level:2},{value:"Predicates",id:"predicates",level:3},{value:"basic_block_entry_node(ControlFlowNode node)",id:"basic_block_entry_nodecontrolflownode-node",level:3},{value:"non_primitive_basic_block_entry_node(ControlFlowNode node",id:"non_primitive_basic_block_entry_nodecontrolflownode-node",level:3},{value:"equalsPrimitiveBasicBlock(BasicBlock bb)",id:"equalsprimitivebasicblockbasicblock-bb",level:3},{value:"basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)",id:"basic_block_membercontrolflownode-node-basicblock-bb-int-pos",level:3},{value:"predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)",id:"predicate-non_primitive_basic_block_membercontrolflownode-node-basicblock-bb-int-pos",level:3},{value:"bb_length(BasicBlock bb)",id:"bb_lengthbasicblock-bb",level:3},{value:"bb_successor_cached(BasicBlock pred, BasicBlock succ)",id:"bb_successor_cachedbasicblock-pred-basicblock-succ",level:3},{value:"BasicBlock",id:"basicblock-1",level:2},{value:"Methods and predicates",id:"methods-and-predicates",level:3},{value:"BasicBlock()",id:"basicblock-2",level:3},{value:"contains(ControlFlowNode node)",id:"containscontrolflownode-node",level:3},{value:"getNode(int pos)",id:"getnodeint-pos",level:3},{value:"getANode()",id:"getanode",level:3},{value:"getASuccessor()",id:"getasuccessor",level:3},{value:"getAPredecessor()",id:"getapredecessor",level:3},{value:"getATrueSuccessor()",id:"getatruesuccessor",level:3},{value:"getAFalseSuccessor()",id:"getafalsesuccessor",level:3},{value:"getEnd()",id:"getend",level:3},{value:"getStart()",id:"getstart",level:3},{value:"length()",id:"length",level:3},{value:"hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn)",id:"haslocationinfostring-filepath-int-startline-int-startcolumn-int-endline-int-endcolumn",level:3},{value:"hasLocationInfoInternal(string file, int line, int col, string endf, int endl, int endc)",id:"haslocationinfointernalstring-file-int-line-int-col-string-endf-int-endl-int-endc",level:3},{value:"getEnclosingFunction()",id:"getenclosingfunction",level:3},{value:"inLoop()",id:"inloop",level:3},{value:"isReachable()",id:"isreachable",level:3},{value:"isUnreachable()",id:"isunreachable",level:3},{value:"EntryBasicBlock",id:"entrybasicblock",level:2},{value:"EntryBasicBlock()",id:"entrybasicblock-1",level:3},{value:"ExitBasicBlock",id:"exitbasicblock",level:2},{value:"ExitBasicBlock(",id:"exitbasicblock-1",level:3},{value:"unreachable(ControlFlowNode n)",id:"unreachablecontrolflownode-n",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"basicblock",children:"BasicBlock"})}),"\n",(0,c.jsxs)(n.p,{children:["Provides a library for reasoning about control flow at the granularity of basic blocks. This is usually much more efficient than reasoning directly at the level of ",(0,c.jsx)(n.code,{children:"ControlFlowNode"}),"s."]}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"BasicBlock"}),"s are refinements of ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s, taking\nimpossible CFG edges into account (using the ",(0,c.jsx)(n.code,{children:"successors_adapted"}),"\nrelation). The refinement manifests itself in two changes:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["The successor relation on ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s uses ",(0,c.jsx)(n.code,{children:"successors_adapted"}),"\n(instead of ",(0,c.jsx)(n.code,{children:"successors_extended"})," used by ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s). Consequently, some edges between ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s may be removed. Example:"]}),"\n"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"x = 1; // s1\nif (true) { // s2\n x = 2; // s3\n} else {\n x = 3; // s4\n}\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"BasicBlock"})," successor edge from the basic block containing ",(0,c.jsx)(n.code,{children:"s1"})," and ",(0,c.jsx)(n.code,{children:"s2"})," to the basic block containing ",(0,c.jsx)(n.code,{children:"s4"})," is removed."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s may be split up into two or more\n",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s: Internal nodes of ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s whose\npredecessor edges have been removed (unreachable code) will be entry points of new ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"s. Consequently, each entry point of a ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"})," will also be an entry point of a ",(0,c.jsx)(n.code,{children:"BasicBlock"}),", but the converse does not necessarily hold. Example:"]}),"\n"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"x = 1; // s5\nabort(); // s6\nx = 2; // s7\n"})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"s5"}),"-",(0,c.jsx)(n.code,{children:"s7"})," belong to the same ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),", but the CFG edge from ",(0,c.jsx)(n.code,{children:"s6"})," to ",(0,c.jsx)(n.code,{children:"s7"})," is impossible, so ",(0,c.jsx)(n.code,{children:"s7"})," will be the entry point of its own (unreachable) ",(0,c.jsx)(n.code,{children:"BasicBlock"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["Note that, although possible, two or more ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),"s are never merged to one ",(0,c.jsx)(n.code,{children:"BasicBlock"}),": Consider the first example above; it would be possible to define a single ",(0,c.jsx)(n.code,{children:"BasicBlock"})," consisting of ",(0,c.jsx)(n.code,{children:"s1"}),"-",(0,c.jsx)(n.code,{children:"s3"}),", however, the result would be counter-intuitive."]}),"\n",(0,c.jsx)(n.h2,{id:"module-classes-and-predicate",children:"Module, Classes and Predicate"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#cached",children:"Cached"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basicblock-1",children:"BasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#entrybasicblock",children:"EntryBasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#exitbasicblock",children:"ExitBasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#unreachablecontrolflownode-n",children:"unreachable(ControlFlowNode n)"})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"cached",children:"Cached"}),"\n",(0,c.jsx)(n.h3,{id:"predicates",children:"Predicates"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basic_block_entry_nodecontrolflownode-node",children:"basic_block_entry_node(ControlFlowNode node)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#non_primitive_basic_block_entry_nodecontrolflownode-node",children:"non_primitive_basic_block_entry_node(ControlFlowNode node)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#equalsprimitivebasicblockbasicblock-bb",children:"equalsPrimitiveBasicBlock(BasicBlock bb)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basic_block_membercontrolflownode-node-basicblock-bb-int-pos",children:"basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#non_primitive_basic_block_entry_nodecontrolflownode-node",children:"non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#bb_lengthbasicblock-bb",children:"bb_length(BasicBlock bb)"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#bb_successor_cachedbasicblock-pred-basicblock-succ",children:"bb_successor_cached(BasicBlock pred, BasicBlock succ)"})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"basic_block_entry_nodecontrolflownode-node",children:"basic_block_entry_node(ControlFlowNode node)"}),"\n",(0,c.jsxs)(n.p,{children:["Any node that is the entry point of a primitive basic block is\nalso the entry point of a basic block. In addition, all nodes\nwith a primitive successor, where the predecessor has been pruned\n(that is, ",(0,c.jsx)(n.code,{children:"getAPredecessor()"})," does not exist while a predecessor\nusing the primitive ",(0,c.jsx)(n.code,{children:"successors_extended"})," relation does exist), is also considered a basic block entry node."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate basic_block_entry_node(ControlFlowNode node) {\n primitive_basic_block_entry_node(node) or\n non_primitive_basic_block_entry_node(node)\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"non_primitive_basic_block_entry_nodecontrolflownode-node",children:"non_primitive_basic_block_entry_node(ControlFlowNode node"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"private predicate non_primitive_basic_block_entry_node(ControlFlowNode node) {\n not primitive_basic_block_entry_node(node) and\n not exists(node.getAPredecessor()) and\n successors_extended(node, _)\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"equalsprimitivebasicblockbasicblock-bb",children:"equalsPrimitiveBasicBlock(BasicBlock bb)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if basic block ",(0,c.jsx)(n.code,{children:"bb"})," equals a primitive basic block."]}),"\n",(0,c.jsx)(n.p,{children:"There are two situations in which this isnot* the case:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["Either the entry node of ",(0,c.jsx)(n.code,{children:"bb"})," does not correspond to an\nentry node of a primitive basic block, or"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"The primitive basic block with the same entry node contains\na (non-entry) node which is the entry node of a non-primitive\nbasic block (that is, the primitive basic block has been split\nup)."}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This predicate is used for performance optimization only:\nWhenever a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," equals a ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlock"}),", we can\nreuse predicates already computed for ",(0,c.jsx)(n.code,{children:"PrimitiveBasicBlocks"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"private predicate equalsPrimitiveBasicBlock(BasicBlock bb) {\n primitive_basic_block_entry_node(bb) and\n not exists(int i |\n i > 0 and\n non_primitive_basic_block_entry_node(bb.(PrimitiveBasicBlock).getNode(i))\n )\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"basic_block_membercontrolflownode-node-basicblock-bb-int-pos",children:"basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if ",(0,c.jsx)(n.code,{children:"node"})," is the ",(0,c.jsx)(n.code,{children:"pos"}),"th control-flow node in basic block ",(0,c.jsx)(n.code,{children:"bb"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"cached predicate basic_block_member(ControlFlowNode node, BasicBlock bb, int pos) {\n equalsPrimitiveBasicBlock(bb) and primitive_basic_block_member(node, bb, pos) // reuse already computed relation\n or\n non_primitive_basic_block_member(node, bb, pos)\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"predicate-non_primitive_basic_block_membercontrolflownode-node-basicblock-bb-int-pos",children:"predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos)"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"private predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos) {\n not equalsPrimitiveBasicBlock(bb) and node = bb and pos = 0\n or\n not node instanceof BasicBlock and\n exists(ControlFlowNode pred | successors_extended(pred, node) |\n non_primitive_basic_block_member(pred, bb, pos - 1)\n )\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"bb_lengthbasicblock-bb",children:"bb_length(BasicBlock bb)"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the number of control-flow nodes in the basic block ",(0,c.jsx)(n.code,{children:"bb"}),"./"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"cached int bb_length(BasicBlock bb) {\n if equalsPrimitiveBasicBlock(bb)\n then result = bb.(PrimitiveBasicBlock).length() // reuse already computed relation\n else result = strictcount(ControlFlowNode node | basic_block_member(node, bb, _))\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"bb_successor_cachedbasicblock-pred-basicblock-succ",children:"bb_successor_cached(BasicBlock pred, BasicBlock succ)"}),"\n",(0,c.jsx)(n.p,{children:"Successor relation for basic blocks."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"cached predicate bb_successor_cached(BasicBlock pred, BasicBlock succ) {\n exists(ControlFlowNode last |\n basic_block_member(last, pred, bb_length(pred) - 1) and\n last.getASuccessor() = succ\n )\n}\n"})}),"\n",(0,c.jsx)(n.h2,{id:"basicblock-1",children:"BasicBlock"}),"\n",(0,c.jsx)(n.p,{children:"A basic block in the Solidity control-flow graph."}),"\n",(0,c.jsx)(n.p,{children:"A basic block is a simple sequence of control-flow nodes,\nconnected to each other and nothing else:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:" A - B - C - D ABCD is a basic block\n"})}),"\n",(0,c.jsx)(n.p,{children:"Any incoming or outgoing edges break the block into two:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:" A - B > C - D AB is a basic block and CD is a basic block (C has two incoming edges)\n\n\n A - B < C - D AB is a basic block and CD is a basic block (B has two outgoing edges)\n"})}),"\n",(0,c.jsx)(n.h3,{id:"methods-and-predicates",children:"Methods and predicates"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#basicblock-2",children:"BasicBlock"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#containscontrolflownode-node",children:"contains"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getnodeint-pos",children:"getNode"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getanode",children:"getANode"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getasuccessor",children:"getASuccessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getapredecessor",children:"getAPredecessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getatruesuccessor",children:"getATrueSuccessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getafalsesuccessor",children:"getAFalseSuccessor"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getend",children:"getEnd"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getstart",children:"getStart"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#length",children:"length"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#haslocationinfostring-filepath-int-startline-int-startcolumn-int-endline-int-endcolumn",children:"hasLocationInfo"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#haslocationinfointernalstring-file-int-line-int-col-string-endf-int-endl-int-endc",children:"hasLocationInfoInternal"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#getenclosingfunction",children:"getEnclosingFunction"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#inloop",children:"inLoop"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#isreachable",children:"isReachable"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#isunreachable",children:"isUnreachable"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#unreachablecontrolflownode-n",children:"unreachable"})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"basicblock-2",children:"BasicBlock()"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock() { basic_block_entry_node(this) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"containscontrolflownode-node",children:"contains(ControlFlowNode node)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if this basic block contains ",(0,c.jsx)(n.code,{children:"node"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate contains(ControlFlowNode node) { basic_block_member(node, this, _) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getnodeint-pos",children:"getNode(int pos)"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," at position ",(0,c.jsx)(n.code,{children:"pos"})," in this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getNode(int pos) { basic_block_member(result, this, pos) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getanode",children:"getANode()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," in this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getANode() { basic_block_member(result, this, _) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getasuccessor",children:"getASuccessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," that is a direct successor of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getASuccessor() { bb_successor(this, result) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getapredecessor",children:"getAPredecessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," that is a direct predecessor of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getAPredecessor() { bb_successor(result, this) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getatruesuccessor",children:"getATrueSuccessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," such that the control-flow edge ",(0,c.jsx)(n.code,{children:"(this, result)"})," may be taken when the outgoing edge of this basic block is an expression that is true."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getATrueSuccessor() { result.getStart() = this.getEnd().getATrueSuccessor() }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getafalsesuccessor",children:"getAFalseSuccessor()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets a ",(0,c.jsx)(n.code,{children:"BasicBlock"})," such that the control-flow edge ",(0,c.jsx)(n.code,{children:"(this, result)"})," may be taken when the outgoing edge of this basic block is an expression that is false."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"BasicBlock getAFalseSuccessor() { result.getStart() = this.getEnd().getAFalseSuccessor() }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getend",children:"getEnd()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the final ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getEnd() { basic_block_member(result, this, bb_length(this) - 1) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getstart",children:"getStart()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the first ",(0,c.jsx)(n.code,{children:"ControlFlowNode"})," of this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ControlFlowNode getStart() { result = this }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"length",children:"length()"}),"\n",(0,c.jsxs)(n.p,{children:["Gets the number of ",(0,c.jsx)(n.code,{children:"ControlFlowNode"}),"s in this basic block."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"int length() { result = bb_length(this) }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"haslocationinfostring-filepath-int-startline-int-startcolumn-int-endline-int-endcolumn",children:"hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn)"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if this element is at the specified location.\nThe location spans column ",(0,c.jsx)(n.code,{children:"startcolumn"})," of line ",(0,c.jsx)(n.code,{children:"startline"})," to column ",(0,c.jsx)(n.code,{children:"endcolumn"})," of line ",(0,c.jsx)(n.code,{children:"endline"})," in file ",(0,c.jsx)(n.code,{children:"filepath"}),". For more information, see\n",(0,c.jsx)(n.a,{href:"https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/",children:"Locations"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"Yields no result if this basic block spans multiple source files."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate hasLocationInfo(\n string filepath, int startline, int startcolumn, int endline, int endcolumn\n ) {\n this.hasLocationInfoInternal(filepath, startline, startcolumn, filepath, endline, endcolumn)\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"haslocationinfointernalstring-file-int-line-int-col-string-endf-int-endl-int-endc",children:"hasLocationInfoInternal(string file, int line, int col, string endf, int endl, int endc)"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:" pragma[noinline]\n private predicate hasLocationInfoInternal(\n string file, int line, int col, string endf, int endl, int endc\n ) {\n this.getStart().getLocation().hasLocationInfo(file, line, col, _, _) and\n this.getEnd().getLocation().hasLocationInfo(endf, _, _, endl, endc)\n }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"getenclosingfunction",children:"getEnclosingFunction()"}),"\n",(0,c.jsx)(n.p,{children:"Gets the function containing this basic block."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"Solidity::FunctionDefinition getEnclosingFunction() { result = this.getStart().getControlFlowScope() }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"inloop",children:"inLoop()"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if this basic block is in a loop of the control-flow graph. This includes loops created by ",(0,c.jsx)(n.code,{children:"goto"})," statements. This predicate may not hold\neven if this basic block is syntactically inside a ",(0,c.jsx)(n.code,{children:"while"})," loop if the necessary back edges are unreachable."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate inLoop() { this.getASuccessor+() = this }\n"})}),"\n",(0,c.jsx)(n.h3,{id:"isreachable",children:"isReachable()"}),"\n",(0,c.jsxs)(n.p,{children:["Holds if control flow may reach this basic block from a function entry point or any handler of a reachable ",(0,c.jsx)(n.code,{children:"try"})," statement."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate isReachable() {\n \n exists(Solidity::FunctionDefinition f | f.getBody() = this)\n or\n exists(BasicBlock pred | pred.getASuccessor() = this and pred.isReachable())\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"isunreachable",children:"isUnreachable()"}),"\n",(0,c.jsxs)(n.p,{children:["Means ",(0,c.jsx)(n.code,{children:"not isReachable()"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate isUnreachable() { not this.isReachable() }\n"})}),"\n",(0,c.jsx)(n.h2,{id:"entrybasicblock",children:"EntryBasicBlock"}),"\n",(0,c.jsx)(n.p,{children:"An entry point of a function."}),"\n",(0,c.jsx)(n.h3,{id:"entrybasicblock-1",children:"EntryBasicBlock()"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"EntryBasicBlock() { exists(Solidity::FunctionDefinition f | this = f.getBody()) }\n"})}),"\n",(0,c.jsx)(n.h2,{id:"exitbasicblock",children:"ExitBasicBlock"}),"\n",(0,c.jsx)(n.p,{children:"A basic block whose last node is the exit point of a function."}),"\n",(0,c.jsx)(n.h3,{id:"exitbasicblock-1",children:"ExitBasicBlock("}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"ExitBasicBlock() {\n this.getEnd() instanceof Solidity::FunctionBody \n // or\n // aborting(this.getEnd())\n}\n"})}),"\n",(0,c.jsx)(n.h2,{id:"unreachablecontrolflownode-n",children:"unreachable(ControlFlowNode n)"}),"\n",(0,c.jsx)(n.p,{children:"Correct relation for reachability of ControlFlowNodes."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"predicate unreachable(ControlFlowNode n) {\n exists(BasicBlock bb | bb.contains(n) and bb.isUnreachable())\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(a,{...e})}):a(e)}},1503:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>r});var c=i(758);const s={},o=c.createContext(s);function l(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac60d37c.63d4a526.js b/assets/js/ac60d37c.63d4a526.js deleted file mode 100644 index de53890..0000000 --- a/assets/js/ac60d37c.63d4a526.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[156],{5208:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var c=t(6070),d=t(1503);const a={},o=void 0,r={id:"README/det04_doc",title:"det04_doc",description:"Dead code",source:"@site/docs/README/det04_doc.md",sourceDirName:"README",slug:"/README/det04_doc",permalink:"/docs/README/det04_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det04_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"det03_doc",permalink:"/docs/README/det03_doc"}},i={},l=[{value:"Dead code",id:"dead-code",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function s(e){const n={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h2,{id:"dead-code",children:"Dead code"}),"\n",(0,c.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector4.ql -d /path-to-database/\n"})}),"\n",(0,c.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,c.jsx)(n.p,{children:"Detects dead code on a CFG level, in the form of unreachable basic blocks."}),"\n",(0,c.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,c.jsx)(n.p,{children:"Eliminate code that can't be executed and thus has no effect in\nthe logic of the final program."}),"\n",(0,c.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,c.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n if(false)\n {\n revert();\n }\n }\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"fixed",children:"Fixed"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n // if(false)\n {\n revert();\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(s,{...e})}):s(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var c=t(758);const d={},a=c.createContext(d);function o(e){const n=c.useContext(a);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:o(e.components),c.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac60d37c.fa593c7a.js b/assets/js/ac60d37c.fa593c7a.js new file mode 100644 index 0000000..d62b2b9 --- /dev/null +++ b/assets/js/ac60d37c.fa593c7a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[156],{5208:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var c=t(6070),d=t(1503);const a={},o=void 0,r={id:"README/det04_doc",title:"det04_doc",description:"Dead code",source:"@site/docs/README/det04_doc.md",sourceDirName:"README",slug:"/README/det04_doc",permalink:"/CyScout/docs/README/det04_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det04_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"det03_doc",permalink:"/CyScout/docs/README/det03_doc"}},i={},l=[{value:"Dead code",id:"dead-code",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function s(e){const n={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h2,{id:"dead-code",children:"Dead code"}),"\n",(0,c.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector4.ql -d /path-to-database/\n"})}),"\n",(0,c.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,c.jsx)(n.p,{children:"Detects dead code on a CFG level, in the form of unreachable basic blocks."}),"\n",(0,c.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,c.jsx)(n.p,{children:"Eliminate code that can't be executed and thus has no effect in\nthe logic of the final program."}),"\n",(0,c.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,c.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n if(false)\n {\n revert();\n }\n }\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"fixed",children:"Fixed"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:"contract A{ \n function a(uint256 t) public {\n // if(false)\n {\n revert();\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(s,{...e})}):s(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var c=t(758);const d={},a=c.createContext(d);function o(e){const n=c.useContext(a);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:o(e.components),c.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b9bd2c8a.0c2be326.js b/assets/js/b9bd2c8a.0c2be326.js new file mode 100644 index 0000000..cf22338 --- /dev/null +++ b/assets/js/b9bd2c8a.0c2be326.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[50],{615:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>a,frontMatter:()=>i,metadata:()=>d,toc:()=>o});var n=s(6070),l=s(1503);const i={},c="Block Statement",d={id:"Classes/Block",title:"Block Statement",description:"Implements a class to model a solidity block statement",source:"@site/docs/Classes/Block.md",sourceDirName:"Classes",slug:"/Classes/Block",permalink:"/CyScout/docs/Classes/Block",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Block.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"BasicBlock",permalink:"/CyScout/docs/Classes/BasicBlock"},next:{title:"Call",permalink:"/CyScout/docs/Classes/Call"}},r={},o=[{value:"Methods",id:"methods",level:2},{value:"getAStmt()",id:"getastmt",level:3},{value:"getStmt(int n)",id:"getstmtint-n",level:3},{value:"getLastStmt()",id:"getlaststmt",level:3},{value:"getLastStmtIn()",id:"getlaststmtin",level:3},{value:"getNumStmt()",id:"getnumstmt",level:3},{value:"isEmpty()",id:"isempty",level:3},{value:"getIndexOfStmt(Stmt s)",id:"getindexofstmtstmt-s",level:3}];function h(e){const t={code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"block-statement",children:"Block Statement"})}),"\n",(0,n.jsx)(t.p,{children:"Implements a class to model a solidity block statement"}),"\n",(0,n.jsx)(t.h2,{id:"methods",children:"Methods"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getAStmt()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getStmt(int n)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getLastStmt()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getLastStmtIn()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getNumStmt()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"isEmpty()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getIndexOfStmt(Stmt s)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"getastmt",children:"getAStmt()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getAStmt() { result = this.getAFieldOrChild() }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets a body statement of this block."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getAStmt()"})," would have 3 results, for the declarations of ",(0,n.jsx)(t.code,{children:"a"})," and ",(0,n.jsx)(t.code,{children:"b"})," and for the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getstmtint-n",children:"getStmt(int n)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getStmt(int n) { result = this.getChild(n) }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Gets the ",(0,n.jsx)(t.code,{children:"n"}),"th body statement of this block, indexed from 0.. For example, for the block"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getStmt(2)"})," result is the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getlaststmt",children:"getLastStmt()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getLastStmt() { result = this.getStmt(this.getNumStmt() - 1) }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the last body statement of this block. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getLastStmt()"})," returns the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getlaststmtin",children:"getLastStmtIn()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getLastStmtIn() {\n if this.getLastStmt().getChild() instanceof BlockStmt\n then result = this.getLastStmt().getChild().(BlockStmt).getLastStmtIn()\n else result = this.getLastStmt()\n}\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the last body statement of the block. If the last statement\nis itself a block, returns the last statement of that block, and so on. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; { a = b; } }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getLastStmtIn()"})," results in the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getnumstmt",children:"getNumStmt()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"int getNumStmt() { result = count(this.getAStmt()) }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the number of body statements in this block. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getNumStmt()"})," gives 3."]}),"\n",(0,n.jsx)(t.h3,{id:"isempty",children:"isEmpty()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"predicate isEmpty() { this.getNumStmt() = 0 }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Holds if the block has no statements. For the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{// a comment}\n"})}),"\n",(0,n.jsx)(t.p,{children:"It returns True."}),"\n",(0,n.jsx)(t.h3,{id:"getindexofstmtstmt-s",children:"getIndexOfStmt(Stmt s)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"int getIndexOfStmt(Stmt s) { this.getStmt(result) = s }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the index of the given statement within this block, indexed from 0. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["if ",(0,n.jsx)(t.code,{children:"s"})," is the expression statement ",(0,n.jsx)(t.code,{children:"a = b"})," then ",(0,n.jsx)(t.code,{children:"getIndexOfStmt(s)"}),"\nhas result 2."]})]})}function a(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1503:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>d});var n=s(758);const l={},i=n.createContext(l);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b9bd2c8a.c0d5e90f.js b/assets/js/b9bd2c8a.c0d5e90f.js deleted file mode 100644 index d023a45..0000000 --- a/assets/js/b9bd2c8a.c0d5e90f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[50],{615:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>a,frontMatter:()=>i,metadata:()=>d,toc:()=>o});var n=s(6070),l=s(1503);const i={},c="Block Statement",d={id:"Classes/Block",title:"Block Statement",description:"Implements a class to model a solidity block statement",source:"@site/docs/Classes/Block.md",sourceDirName:"Classes",slug:"/Classes/Block",permalink:"/docs/Classes/Block",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Block.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"BasicBlock",permalink:"/docs/Classes/BasicBlock"},next:{title:"Call",permalink:"/docs/Classes/Call"}},r={},o=[{value:"Methods",id:"methods",level:2},{value:"getAStmt()",id:"getastmt",level:3},{value:"getStmt(int n)",id:"getstmtint-n",level:3},{value:"getLastStmt()",id:"getlaststmt",level:3},{value:"getLastStmtIn()",id:"getlaststmtin",level:3},{value:"getNumStmt()",id:"getnumstmt",level:3},{value:"isEmpty()",id:"isempty",level:3},{value:"getIndexOfStmt(Stmt s)",id:"getindexofstmtstmt-s",level:3}];function h(e){const t={code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"block-statement",children:"Block Statement"})}),"\n",(0,n.jsx)(t.p,{children:"Implements a class to model a solidity block statement"}),"\n",(0,n.jsx)(t.h2,{id:"methods",children:"Methods"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getAStmt()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getStmt(int n)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getLastStmt()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getLastStmtIn()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getNumStmt()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"isEmpty()"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"getIndexOfStmt(Stmt s)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"toString()"})}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"getastmt",children:"getAStmt()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getAStmt() { result = this.getAFieldOrChild() }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets a body statement of this block."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getAStmt()"})," would have 3 results, for the declarations of ",(0,n.jsx)(t.code,{children:"a"})," and ",(0,n.jsx)(t.code,{children:"b"})," and for the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getstmtint-n",children:"getStmt(int n)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getStmt(int n) { result = this.getChild(n) }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Gets the ",(0,n.jsx)(t.code,{children:"n"}),"th body statement of this block, indexed from 0.. For example, for the block"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getStmt(2)"})," result is the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getlaststmt",children:"getLastStmt()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getLastStmt() { result = this.getStmt(this.getNumStmt() - 1) }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the last body statement of this block. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getLastStmt()"})," returns the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getlaststmtin",children:"getLastStmtIn()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Stmt getLastStmtIn() {\n if this.getLastStmt().getChild() instanceof BlockStmt\n then result = this.getLastStmt().getChild().(BlockStmt).getLastStmtIn()\n else result = this.getLastStmt()\n}\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the last body statement of the block. If the last statement\nis itself a block, returns the last statement of that block, and so on. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; { a = b; } }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getLastStmtIn()"})," results in the expression statement ",(0,n.jsx)(t.code,{children:"a = b"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"getnumstmt",children:"getNumStmt()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"int getNumStmt() { result = count(this.getAStmt()) }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the number of body statements in this block. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"getNumStmt()"})," gives 3."]}),"\n",(0,n.jsx)(t.h3,{id:"isempty",children:"isEmpty()"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"predicate isEmpty() { this.getNumStmt() = 0 }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Holds if the block has no statements. For the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{// a comment}\n"})}),"\n",(0,n.jsx)(t.p,{children:"It returns True."}),"\n",(0,n.jsx)(t.h3,{id:"getindexofstmtstmt-s",children:"getIndexOfStmt(Stmt s)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"int getIndexOfStmt(Stmt s) { this.getStmt(result) = s }\n"})}),"\n",(0,n.jsx)(t.p,{children:"Gets the index of the given statement within this block, indexed from 0. For example, for the block"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"{ int a; int b = 1; a = b; }\n"})}),"\n",(0,n.jsxs)(t.p,{children:["if ",(0,n.jsx)(t.code,{children:"s"})," is the expression statement ",(0,n.jsx)(t.code,{children:"a = b"})," then ",(0,n.jsx)(t.code,{children:"getIndexOfStmt(s)"}),"\nhas result 2."]})]})}function a(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1503:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>d});var n=s(758);const l={},i=n.createContext(l);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c008dd48.56cb1d9e.js b/assets/js/c008dd48.56cb1d9e.js new file mode 100644 index 0000000..4833f5c --- /dev/null +++ b/assets/js/c008dd48.56cb1d9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[446],{3383:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=o(6070),n=o(1503);const r={},a=void 0,i={id:"Detectors/msg-value-in-for-loop",title:"msg-value-in-for-loop",description:"msg.value in for loops",source:"@site/docs/Detectors/msg-value-in-for-loop.md",sourceDirName:"Detectors",slug:"/Detectors/msg-value-in-for-loop",permalink:"/CyScout/docs/Detectors/msg-value-in-for-loop",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/msg-value-in-for-loop.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"is-unreachable",permalink:"/CyScout/docs/Detectors/is-unreachable"},next:{title:"transfer-from",permalink:"/CyScout/docs/Detectors/transfer-from"}},c={},l=[{value:"msg.value in for loops",id:"msgvalue-in-for-loops",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3}];function d(e){const t={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"msgvalue-in-for-loops",children:"msg.value in for loops"}),"\n",(0,s.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsx)(t.p,{children:"First you need to create the solidity database for the smart contract."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\n codeql database create {your_path}/solidity-test/test-msg-value-db -l solidity -s {your_path}/solidity-test/solidity-msg-value --search-path {your_path}/solidity/extractor-pack\n\n"})}),"\n",(0,s.jsx)(t.p,{children:"Once you have the database, you can run the detector"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\ncodeql query run {your_path}/solidity/ql/lib/msg-value-in-loop.ql -d {your_path}/solidity-test/test-msg-value-db\n\n"})}),"\n",(0,s.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(t.p,{children:["This detector checks if ",(0,s.jsx)(t.code,{children:"msg.value"})," is inside a for loop. Since ",(0,s.jsx)(t.code,{children:"msg.value"})," is a constant value, it does not change during an iteration and it can produce unwanted behaviour if used incorrectly."]}),"\n",(0,s.jsx)(t.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,s.jsxs)(t.p,{children:["It is recommended to use ",(0,s.jsx)(t.code,{children:"msg.value"})," only once."]})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1503:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>i});var s=o(758);const n={},r=s.createContext(n);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c008dd48.d69df9f1.js b/assets/js/c008dd48.d69df9f1.js deleted file mode 100644 index 18c5e2f..0000000 --- a/assets/js/c008dd48.d69df9f1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[446],{3383:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=o(6070),n=o(1503);const r={},a=void 0,i={id:"Detectors/msg-value-in-for-loop",title:"msg-value-in-for-loop",description:"msg.value in for loops",source:"@site/docs/Detectors/msg-value-in-for-loop.md",sourceDirName:"Detectors",slug:"/Detectors/msg-value-in-for-loop",permalink:"/docs/Detectors/msg-value-in-for-loop",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/msg-value-in-for-loop.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"is-unreachable",permalink:"/docs/Detectors/is-unreachable"},next:{title:"transfer-from",permalink:"/docs/Detectors/transfer-from"}},c={},l=[{value:"msg.value in for loops",id:"msgvalue-in-for-loops",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3}];function d(e){const t={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"msgvalue-in-for-loops",children:"msg.value in for loops"}),"\n",(0,s.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsx)(t.p,{children:"First you need to create the solidity database for the smart contract."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\n codeql database create {your_path}/solidity-test/test-msg-value-db -l solidity -s {your_path}/solidity-test/solidity-msg-value --search-path {your_path}/solidity/extractor-pack\n\n"})}),"\n",(0,s.jsx)(t.p,{children:"Once you have the database, you can run the detector"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\ncodeql query run {your_path}/solidity/ql/lib/msg-value-in-loop.ql -d {your_path}/solidity-test/test-msg-value-db\n\n"})}),"\n",(0,s.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(t.p,{children:["This detector checks if ",(0,s.jsx)(t.code,{children:"msg.value"})," is inside a for loop. Since ",(0,s.jsx)(t.code,{children:"msg.value"})," is a constant value, it does not change during an iteration and it can produce unwanted behaviour if used incorrectly."]}),"\n",(0,s.jsx)(t.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,s.jsxs)(t.p,{children:["It is recommended to use ",(0,s.jsx)(t.code,{children:"msg.value"})," only once."]})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1503:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>i});var s=o(758);const n={},r=s.createContext(n);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/df5b53bc.02ff028b.js b/assets/js/df5b53bc.02ff028b.js new file mode 100644 index 0000000..9a5bd8c --- /dev/null +++ b/assets/js/df5b53bc.02ff028b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[421],{6344:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>a});var t=n(6070),c=n(1503);const r={},l="Index",i={id:"Classes/classesIndex",title:"Index",description:"- Access",source:"@site/docs/Classes/classesIndex.md",sourceDirName:"Classes",slug:"/Classes/classesIndex",permalink:"/CyScout/docs/Classes/classesIndex",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/classesIndex.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Variable",permalink:"/CyScout/docs/Classes/Variable"},next:{title:"Detectors Index",permalink:"/CyScout/docs/Detectors/"}},o={},a=[];function d(e){const s={h1:"h1",header:"header",li:"li",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"index",children:"Index"})}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Access"}),"\n",(0,t.jsx)(s.li,{children:"BasicBlock"}),"\n",(0,t.jsx)(s.li,{children:"Block"}),"\n",(0,t.jsx)(s.li,{children:"Call"}),"\n",(0,t.jsx)(s.li,{children:"ControlFlowGraph"}),"\n",(0,t.jsx)(s.li,{children:"Enclosing"}),"\n",(0,t.jsx)(s.li,{children:"Function"}),"\n",(0,t.jsx)(s.li,{children:"Specifier"}),"\n",(0,t.jsx)(s.li,{children:"SubBasicBlock"}),"\n"]})]})}function u(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1503:(e,s,n)=>{n.d(s,{R:()=>l,x:()=>i});var t=n(758);const c={},r=t.createContext(c);function l(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:l(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/df5b53bc.a89a8268.js b/assets/js/df5b53bc.a89a8268.js deleted file mode 100644 index 1302f70..0000000 --- a/assets/js/df5b53bc.a89a8268.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[421],{6344:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>a});var t=n(6070),c=n(1503);const r={},l="Index",i={id:"Classes/classesIndex",title:"Index",description:"- Access",source:"@site/docs/Classes/classesIndex.md",sourceDirName:"Classes",slug:"/Classes/classesIndex",permalink:"/docs/Classes/classesIndex",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/classesIndex.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Variable",permalink:"/docs/Classes/Variable"},next:{title:"Detectors Index",permalink:"/docs/Detectors/"}},o={},a=[];function d(e){const s={h1:"h1",header:"header",li:"li",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"index",children:"Index"})}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Access"}),"\n",(0,t.jsx)(s.li,{children:"BasicBlock"}),"\n",(0,t.jsx)(s.li,{children:"Block"}),"\n",(0,t.jsx)(s.li,{children:"Call"}),"\n",(0,t.jsx)(s.li,{children:"ControlFlowGraph"}),"\n",(0,t.jsx)(s.li,{children:"Enclosing"}),"\n",(0,t.jsx)(s.li,{children:"Function"}),"\n",(0,t.jsx)(s.li,{children:"Specifier"}),"\n",(0,t.jsx)(s.li,{children:"SubBasicBlock"}),"\n"]})]})}function u(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1503:(e,s,n)=>{n.d(s,{R:()=>l,x:()=>i});var t=n(758);const c={},r=t.createContext(c);function l(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:l(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e6bcf343.ecabe918.js b/assets/js/e6bcf343.ecabe918.js new file mode 100644 index 0000000..77b55cd --- /dev/null +++ b/assets/js/e6bcf343.ecabe918.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[769],{266:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var o=t(6070),d=t(1503);const c={},r=void 0,i={id:"README/det02_doc",title:"det02_doc",description:"'FIX' word in comments",source:"@site/docs/README/det02_doc.md",sourceDirName:"README",slug:"/README/det02_doc",permalink:"/CyScout/docs/README/det02_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det02_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"det01_doc",permalink:"/CyScout/docs/README/det01_doc"},next:{title:"det03_doc",permalink:"/CyScout/docs/README/det03_doc"}},s={},l=[{value:"'FIX' word in comments",id:"fix-word-in-comments",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function a(e){const n={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"fix-word-in-comments",children:"'FIX' word in comments"}),"\n",(0,o.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector2.ql -d /path-to-database/\n"})}),"\n",(0,o.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,o.jsx)(n.p,{children:"Detects the presence of the word 'FIX' in\ncomments."}),"\n",(0,o.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,o.jsx)(n.p,{children:"Fix any identified problems before pushing code to production\nand erase the comments, as these may otherwise expose vulnerable points."}),"\n",(0,o.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,o.jsx)(n.h3,{id:"fixed",children:"Fixed"})]})}function u(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var o=t(758);const d={},c=o.createContext(d);function r(e){const n=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),o.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e6bcf343.f4c13b9b.js b/assets/js/e6bcf343.f4c13b9b.js deleted file mode 100644 index f9d2fc4..0000000 --- a/assets/js/e6bcf343.f4c13b9b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[769],{266:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>c,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var o=t(6070),d=t(1503);const r={},c=void 0,i={id:"README/det02_doc",title:"det02_doc",description:"'FIX' word in comments",source:"@site/docs/README/det02_doc.md",sourceDirName:"README",slug:"/README/det02_doc",permalink:"/docs/README/det02_doc",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/README/det02_doc.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"det01_doc",permalink:"/docs/README/det01_doc"},next:{title:"det03_doc",permalink:"/docs/README/det03_doc"}},s={},l=[{value:"'FIX' word in comments",id:"fix-word-in-comments",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function a(e){const n={code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h2,{id:"fix-word-in-comments",children:"'FIX' word in comments"}),"\n",(0,o.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/detector2.ql -d /path-to-database/\n"})}),"\n",(0,o.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,o.jsx)(n.p,{children:"Detects the presence of the word 'FIX' in\ncomments."}),"\n",(0,o.jsx)(n.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,o.jsx)(n.p,{children:"Fix any identified problems before pushing code to production\nand erase the comments, as these may otherwise expose vulnerable points."}),"\n",(0,o.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,o.jsx)(n.h3,{id:"fixed",children:"Fixed"})]})}function u(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(758);const d={},r=o.createContext(d);function c(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:c(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ee456a43.95cd4e46.js b/assets/js/ee456a43.95cd4e46.js new file mode 100644 index 0000000..d2b7085 --- /dev/null +++ b/assets/js/ee456a43.95cd4e46.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[808],{1636:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>r,toc:()=>d});var s=t(6070),i=t(1503);const l={},o="Enclosing",r={id:"Classes/Enclosing",title:"Enclosing",description:"Provides predicates for finding the smallest element that encloses an expression or statement.",source:"@site/docs/Classes/Enclosing.md",sourceDirName:"Classes",slug:"/Classes/Enclosing",permalink:"/CyScout/docs/Classes/Enclosing",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Enclosing.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Control Flow Graph",permalink:"/CyScout/docs/Classes/ControlFlowGraph"},next:{title:"Function",permalink:"/CyScout/docs/Classes/Function"}},c={},d=[{value:"Functions",id:"functions",level:2},{value:"stmtEnclosingElement(Solidity::Statement s)",id:"stmtenclosingelementsoliditystatement-s",level:2},{value:"exprEnclosingElement(Solidity::Expression e)",id:"exprenclosingelementsolidityexpression-e",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"enclosing",children:"Enclosing"})}),"\n",(0,s.jsx)(n.p,{children:"Provides predicates for finding the smallest element that encloses an expression or statement."}),"\n",(0,s.jsx)(n.h2,{id:"functions",children:"Functions"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#stmtenclosingelementsoliditystatement-s",children:"stmtEnclosingElement(Solidity::Statement s)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#exprenclosingelementsolidityexpression-e",children:"exprEnclosingElement(Solidity::Expression e)"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"stmtenclosingelementsoliditystatement-s",children:"stmtEnclosingElement(Solidity::Statement s)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"AstNode stmtEnclosingElement(Solidity::Statement s) {\n result.(Solidity::FunctionDefinition).getBody().getChild(_) = s or\n result = stmtEnclosingElement(s.getParent()) or\n result = exprEnclosingElement(s.getParent())\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Gets the enclosing element of statement ",(0,s.jsx)(n.code,{children:"s"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"exprenclosingelementsolidityexpression-e",children:"exprEnclosingElement(Solidity::Expression e)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"AstNode exprEnclosingElement(Solidity::Expression e) {\n result = exprEnclosingElement(e.getParent())\n or\n result = stmtEnclosingElement(e.getParent())\n or\n result.(Solidity::FunctionBody) = e.getParent()\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Gets the enclosing element of expression ",(0,s.jsx)(n.code,{children:"e"}),"."]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(758);const i={},l=s.createContext(i);function o(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ee456a43.dd1312b4.js b/assets/js/ee456a43.dd1312b4.js deleted file mode 100644 index 0493f2e..0000000 --- a/assets/js/ee456a43.dd1312b4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[808],{1636:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>r,toc:()=>d});var s=t(6070),i=t(1503);const l={},o="Enclosing",r={id:"Classes/Enclosing",title:"Enclosing",description:"Provides predicates for finding the smallest element that encloses an expression or statement.",source:"@site/docs/Classes/Enclosing.md",sourceDirName:"Classes",slug:"/Classes/Enclosing",permalink:"/docs/Classes/Enclosing",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Classes/Enclosing.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Control Flow Graph",permalink:"/docs/Classes/ControlFlowGraph"},next:{title:"Function",permalink:"/docs/Classes/Function"}},c={},d=[{value:"Functions",id:"functions",level:2},{value:"stmtEnclosingElement(Solidity::Statement s)",id:"stmtenclosingelementsoliditystatement-s",level:2},{value:"exprEnclosingElement(Solidity::Expression e)",id:"exprenclosingelementsolidityexpression-e",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"enclosing",children:"Enclosing"})}),"\n",(0,s.jsx)(n.p,{children:"Provides predicates for finding the smallest element that encloses an expression or statement."}),"\n",(0,s.jsx)(n.h2,{id:"functions",children:"Functions"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#stmtenclosingelementsoliditystatement-s",children:"stmtEnclosingElement(Solidity::Statement s)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#exprenclosingelementsolidityexpression-e",children:"exprEnclosingElement(Solidity::Expression e)"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"stmtenclosingelementsoliditystatement-s",children:"stmtEnclosingElement(Solidity::Statement s)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"AstNode stmtEnclosingElement(Solidity::Statement s) {\n result.(Solidity::FunctionDefinition).getBody().getChild(_) = s or\n result = stmtEnclosingElement(s.getParent()) or\n result = exprEnclosingElement(s.getParent())\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Gets the enclosing element of statement ",(0,s.jsx)(n.code,{children:"s"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"exprenclosingelementsolidityexpression-e",children:"exprEnclosingElement(Solidity::Expression e)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"AstNode exprEnclosingElement(Solidity::Expression e) {\n result = exprEnclosingElement(e.getParent())\n or\n result = stmtEnclosingElement(e.getParent())\n or\n result.(Solidity::FunctionBody) = e.getParent()\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Gets the enclosing element of expression ",(0,s.jsx)(n.code,{children:"e"}),"."]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1503:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(758);const i={},l=s.createContext(i);function o(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f11328d7.bf83e2c6.js b/assets/js/f11328d7.bf83e2c6.js new file mode 100644 index 0000000..b5c7b6b --- /dev/null +++ b/assets/js/f11328d7.bf83e2c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[221],{1143:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var t=n(6070),s=n(1503);const a={},o=void 0,c={id:"Detectors/transfer-from",title:"transfer-from",description:"transfer-from uses arbitrary from",source:"@site/docs/Detectors/transfer-from.md",sourceDirName:"Detectors",slug:"/Detectors/transfer-from",permalink:"/CyScout/docs/Detectors/transfer-from",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/transfer-from.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"msg-value-in-for-loop",permalink:"/CyScout/docs/Detectors/msg-value-in-for-loop"},next:{title:"Unchecked Send",permalink:"/CyScout/docs/Detectors/unchecked-send"}},i={},d=[{value:"transfer-from uses arbitrary from",id:"transfer-from-uses-arbitrary-from",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function l(e){const r={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(r.h2,{id:"transfer-from-uses-arbitrary-from",children:["transfer-from uses arbitrary ",(0,t.jsx)(r.code,{children:"from"})]}),"\n",(0,t.jsx)(r.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/slither-arbitrary-send-erc20.ql -d /path-to-database/\n"})}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["Based on the ",(0,t.jsx)(r.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom",children:"arbitrary-send-erc20"})," detector from Slither.\nDetects wrongful usage of an arbitrary ",(0,t.jsx)(r.code,{children:"from"})," variable\nin a transfer call."]}),"\n",(0,t.jsx)(r.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,t.jsxs)(r.p,{children:["Use ",(0,t.jsx)(r.code,{children:"msg.sender"})," instead."]}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(from, to, amount);\n }\n}\n"})}),"\n",(0,t.jsx)(r.h3,{id:"fixed",children:"Fixed"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(msg.sender, to, amount);\n }\n}\n"})})]})}function u(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1503:(e,r,n)=>{n.d(r,{R:()=>o,x:()=>c});var t=n(758);const s={},a=t.createContext(s);function o(e){const r=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function c(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(a.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f11328d7.f91d561a.js b/assets/js/f11328d7.f91d561a.js deleted file mode 100644 index 3afbde1..0000000 --- a/assets/js/f11328d7.f91d561a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[221],{1143:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var t=n(6070),s=n(1503);const a={},o=void 0,c={id:"Detectors/transfer-from",title:"transfer-from",description:"transfer-from uses arbitrary from",source:"@site/docs/Detectors/transfer-from.md",sourceDirName:"Detectors",slug:"/Detectors/transfer-from",permalink:"/docs/Detectors/transfer-from",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/transfer-from.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"msg-value-in-for-loop",permalink:"/docs/Detectors/msg-value-in-for-loop"},next:{title:"Unchecked Send",permalink:"/docs/Detectors/unchecked-send"}},i={},d=[{value:"transfer-from uses arbitrary from",id:"transfer-from-uses-arbitrary-from",level:2},{value:"Usage",id:"usage",level:2},{value:"Description",id:"description",level:2},{value:"Recomendation",id:"recomendation",level:3},{value:"Example",id:"example",level:2},{value:"Vulnerable",id:"vulnerable",level:3},{value:"Fixed",id:"fixed",level:3}];function l(e){const r={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(r.h2,{id:"transfer-from-uses-arbitrary-from",children:["transfer-from uses arbitrary ",(0,t.jsx)(r.code,{children:"from"})]}),"\n",(0,t.jsx)(r.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"codeql query run codeql-research/solidity/ql/lib/slither-arbitrary-send-erc20.ql -d /path-to-database/\n"})}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["Based on the ",(0,t.jsx)(r.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom",children:"arbitrary-send-erc20"})," detector from Slither.\nDetects wrongful usage of an arbitrary ",(0,t.jsx)(r.code,{children:"from"})," variable\nin a transfer call."]}),"\n",(0,t.jsx)(r.h3,{id:"recomendation",children:"Recomendation"}),"\n",(0,t.jsxs)(r.p,{children:["Use ",(0,t.jsx)(r.code,{children:"msg.sender"})," instead."]}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.h3,{id:"vulnerable",children:"Vulnerable"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(from, to, amount);\n }\n}\n"})}),"\n",(0,t.jsx)(r.h3,{id:"fixed",children:"Fixed"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"contract A{ \n function a(address from, address to, uint256 amount) public {\n erc20.transferFrom(msg.sender, to, amount);\n }\n}\n"})})]})}function u(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1503:(e,r,n)=>{n.d(r,{R:()=>o,x:()=>c});var t=n(758);const s={},a=t.createContext(s);function o(e){const r=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function c(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(a.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1c56182.3c015b2c.js b/assets/js/f1c56182.3c015b2c.js new file mode 100644 index 0000000..5af9347 --- /dev/null +++ b/assets/js/f1c56182.3c015b2c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[829],{9036:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>s,toc:()=>a});var o=n(6070),r=n(1503);const c={},i="Incorrect exponentiation",s={id:"Detectors/incorrect-exp",title:"Incorrect exponentiation",description:"Description",source:"@site/docs/Detectors/incorrect-exp.md",sourceDirName:"Detectors",slug:"/Detectors/incorrect-exp",permalink:"/CyScout/docs/Detectors/incorrect-exp",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/incorrect-exp.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Divide before multiply",permalink:"/CyScout/docs/Detectors/divide-before-multiply"},next:{title:"incorrect-shift",permalink:"/CyScout/docs/Detectors/incorrect-shift"}},d={},a=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"incorrect-exponentiation",children:"Incorrect exponentiation"})}),"\n",(0,o.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,o.jsxs)(t.p,{children:["Based on Slither's ",(0,o.jsx)(t.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-exponentiation",children:"incorrect-exp detector"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["Detect use of bitwise xor ",(0,o.jsx)(t.code,{children:"^"})," instead of exponential ",(0,o.jsx)(t.code,{children:"**"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"contract Bug{\n uint UINT_MAX = 2^256 - 1;\n ...\n}\n"})}),"\n",(0,o.jsxs)(t.p,{children:["Alice deploys a contract in which ",(0,o.jsx)(t.code,{children:"UINT_MAX"})," incorrectly uses ",(0,o.jsx)(t.code,{children:"^"})," operator instead of ",(0,o.jsx)(t.code,{children:"**"})," for exponentiation"]}),"\n",(0,o.jsx)(t.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,o.jsxs)(t.p,{children:["Use the correct operator ",(0,o.jsx)(t.code,{children:"**"})," for exponentiation."]})]})}function p(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},1503:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var o=n(758);const r={},c=o.createContext(r);function i(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1c56182.4b7f8cfc.js b/assets/js/f1c56182.4b7f8cfc.js deleted file mode 100644 index ad40b87..0000000 --- a/assets/js/f1c56182.4b7f8cfc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[829],{9036:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>s,toc:()=>a});var r=n(6070),o=n(1503);const c={},i="Incorrect exponentiation",s={id:"Detectors/incorrect-exp",title:"Incorrect exponentiation",description:"Description",source:"@site/docs/Detectors/incorrect-exp.md",sourceDirName:"Detectors",slug:"/Detectors/incorrect-exp",permalink:"/docs/Detectors/incorrect-exp",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/incorrect-exp.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Divide before multiply",permalink:"/docs/Detectors/divide-before-multiply"},next:{title:"incorrect-shift",permalink:"/docs/Detectors/incorrect-shift"}},d={},a=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"incorrect-exponentiation",children:"Incorrect exponentiation"})}),"\n",(0,r.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(t.p,{children:["Based on Slither's ",(0,r.jsx)(t.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-exponentiation",children:"incorrect-exp detector"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Detect use of bitwise xor ",(0,r.jsx)(t.code,{children:"^"})," instead of exponential ",(0,r.jsx)(t.code,{children:"**"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"contract Bug{\n uint UINT_MAX = 2^256 - 1;\n ...\n}\n"})}),"\n",(0,r.jsxs)(t.p,{children:["Alice deploys a contract in which ",(0,r.jsx)(t.code,{children:"UINT_MAX"})," incorrectly uses ",(0,r.jsx)(t.code,{children:"^"})," operator instead of ",(0,r.jsx)(t.code,{children:"**"})," for exponentiation"]}),"\n",(0,r.jsx)(t.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,r.jsxs)(t.p,{children:["Use the correct operator ",(0,r.jsx)(t.code,{children:"**"})," for exponentiation."]})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1503:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var r=n(758);const o={},c=r.createContext(o);function i(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f4dff024.0045e42f.js b/assets/js/f4dff024.0045e42f.js new file mode 100644 index 0000000..f2cd286 --- /dev/null +++ b/assets/js/f4dff024.0045e42f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[351],{2207:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var n=i(6070),o=i(1503);const r={},c="Divide before multiply",s={id:"Detectors/divide-before-multiply",title:"Divide before multiply",description:"Description",source:"@site/docs/Detectors/divide-before-multiply.md",sourceDirName:"Detectors",slug:"/Detectors/divide-before-multiply",permalink:"/CyScout/docs/Detectors/divide-before-multiply",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/divide-before-multiply.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Detectors Index",permalink:"/CyScout/docs/Detectors/"},next:{title:"Incorrect exponentiation",permalink:"/CyScout/docs/Detectors/incorrect-exp"}},l={},d=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"divide-before-multiply",children:"Divide before multiply"})}),"\n",(0,n.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(t.p,{children:["Based on Slither's ",(0,n.jsx)(t.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply",children:"divide-before-multiply detector"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Solidity's integer division truncates. Thus, performing division before multiplication can lead to precision loss."}),"\n",(0,n.jsx)(t.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"contract A {\n\tfunction f(uint n) public {\n coins = (oldSupply / n) * interest;\n }\n}\n"})}),"\n",(0,n.jsxs)(t.p,{children:["If n is greater than oldSupply, coins will be zero. For example, with ",(0,n.jsx)(t.code,{children:"oldSupply = 5; n = 10, interest = 2"}),", coins will be zero.\nIf ",(0,n.jsx)(t.code,{children:"(oldSupply * interest / n)"})," was used, coins would have been 1.\nIn general, it's usually a good idea to re-arrange arithmetic to perform multiplication before division, unless the limit of a smaller type makes this dangerous."]}),"\n",(0,n.jsx)(t.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,n.jsx)(t.p,{children:"Consider ordering multiplication before division."})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},1503:(e,t,i)=>{i.d(t,{R:()=>c,x:()=>s});var n=i(758);const o={},r=n.createContext(o);function c(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f4dff024.c01042bc.js b/assets/js/f4dff024.c01042bc.js deleted file mode 100644 index b3e2401..0000000 --- a/assets/js/f4dff024.c01042bc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[351],{2207:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var n=t(6070),o=t(1503);const r={},s="Divide before multiply",c={id:"Detectors/divide-before-multiply",title:"Divide before multiply",description:"Description",source:"@site/docs/Detectors/divide-before-multiply.md",sourceDirName:"Detectors",slug:"/Detectors/divide-before-multiply",permalink:"/docs/Detectors/divide-before-multiply",draft:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/docs/Detectors/divide-before-multiply.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Detectors Index",permalink:"/docs/Detectors/"},next:{title:"Incorrect exponentiation",permalink:"/docs/Detectors/incorrect-exp"}},l={},d=[{value:"Description",id:"description",level:2},{value:"Exploit Scenario:",id:"exploit-scenario",level:2},{value:"Recommendation",id:"recommendation",level:2}];function a(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.header,{children:(0,n.jsx)(i.h1,{id:"divide-before-multiply",children:"Divide before multiply"})}),"\n",(0,n.jsx)(i.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(i.p,{children:["Based on Slither's ",(0,n.jsx)(i.a,{href:"https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply",children:"divide-before-multiply detector"}),"."]}),"\n",(0,n.jsx)(i.p,{children:"Solidity's integer division truncates. Thus, performing division before multiplication can lead to precision loss."}),"\n",(0,n.jsx)(i.h2,{id:"exploit-scenario",children:"Exploit Scenario:"}),"\n",(0,n.jsx)(i.pre,{children:(0,n.jsx)(i.code,{children:"contract A {\n\tfunction f(uint n) public {\n coins = (oldSupply / n) * interest;\n }\n}\n"})}),"\n",(0,n.jsxs)(i.p,{children:["If n is greater than oldSupply, coins will be zero. For example, with ",(0,n.jsx)(i.code,{children:"oldSupply = 5; n = 10, interest = 2"}),", coins will be zero.\nIf ",(0,n.jsx)(i.code,{children:"(oldSupply * interest / n)"})," was used, coins would have been 1.\nIn general, it's usually a good idea to re-arrange arithmetic to perform multiplication before division, unless the limit of a smaller type makes this dangerous."]}),"\n",(0,n.jsx)(i.h2,{id:"recommendation",children:"Recommendation"}),"\n",(0,n.jsx)(i.p,{children:"Consider ordering multiplication before division."})]})}function p(e={}){const{wrapper:i}={...(0,o.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},1503:(e,i,t)=>{t.d(i,{R:()=>s,x:()=>c});var n=t(758);const o={},r=n.createContext(o);function s(e){const i=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.764f447a.js b/assets/js/main.764f447a.js new file mode 100644 index 0000000..b9b62e3 --- /dev/null +++ b/assets/js/main.764f447a.js @@ -0,0 +1,2 @@ +/*! For license information please see main.764f447a.js.LICENSE.txt */ +(self.webpackChunkcodeql_research=self.webpackChunkcodeql_research||[]).push([[792],{7333:(e,t,n)=>{var r={"./":6532};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=7333},6452:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});n(758);var r=n(4355),o=n.n(r),a=n(4054);const i={"0fedfb09":[()=>n.e(871).then(n.bind(n,8572)),"@site/docs/Classes/Function.md",8572],17896441:[()=>Promise.all([n.e(869),n.e(968),n.e(401)]).then(n.bind(n,8999)),"@theme/DocItem",8999],"1e4ea422":[()=>n.e(575).then(n.bind(n,7745)),"@site/docs/Detectors/index.md",7745],"1f391b9e":[()=>Promise.all([n.e(869),n.e(968),n.e(61)]).then(n.bind(n,6173)),"@theme/MDXPage",6173],"393be207":[()=>n.e(134).then(n.bind(n,4561)),"@site/src/pages/markdown-page.md",4561],"4b0e7aa3":[()=>n.e(568).then(n.bind(n,484)),"@site/docs/README/readme.md",484],"5e95c892":[()=>n.e(647).then(n.bind(n,4195)),"@theme/DocsRoot",4195],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"649e0194":[()=>n.e(789).then(n.bind(n,4763)),"@site/docs/README/det01_doc.md",4763],"68781f40":[()=>n.e(669).then(n.bind(n,323)),"@site/docs/Detectors/incorrect-shift.md",323],"69f4f467":[()=>n.e(405).then(n.bind(n,6124)),"@site/docs/Detectors/unchecked-send.md",6124],"6b120e63":[()=>n.e(962).then(n.bind(n,6842)),"@site/docs/Detectors/is-unreachable.md",6842],"74e2df82":[()=>n.e(235).then(n.bind(n,5698)),"@site/docs/Classes/Access.md",5698],"79321e3a":[()=>n.e(826).then(n.bind(n,5257)),"@site/docs/README/det03_doc.md",5257],"796aa2a1":[()=>n.e(519).then(n.bind(n,4681)),"@site/docs/Classes/Specifier.md",4681],"83a8eaf6":[()=>n.e(537).then(n.bind(n,6295)),"@site/docs/Classes/ControlFlowGraph.md",6295],"84e25d9a":[()=>n.e(591).then(n.bind(n,8831)),"@site/docs/Classes/SubBasicBlock.md",8831],"8c56a58b":[()=>n.e(613).then(n.bind(n,3312)),"@site/docs/Detectors/unprotected-self-destruct.md",3312],"94ad6ac6":[()=>n.e(487).then(n.bind(n,4016)),"@site/docs/Classes/Variable.md",4016],"9567510c":[()=>n.e(165).then(n.bind(n,428)),"@site/docs/Classes/Call.md",428],"9cb5c5d3":[()=>n.e(891).then(n.t.bind(n,1465,19)),"@generated/docusaurus-plugin-content-docs/default/p/cy-scout-docs-34a.json",1465],a7456010:[()=>n.e(616).then(n.t.bind(n,8552,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",8552],a7bd4aaa:[()=>n.e(98).then(n.bind(n,4449)),"@theme/DocVersionRoot",4449],a94703ab:[()=>Promise.all([n.e(869),n.e(48)]).then(n.bind(n,3789)),"@theme/DocRoot",3789],aa80dae2:[()=>n.e(309).then(n.bind(n,6575)),"@site/docs/Classes/BasicBlock.md",6575],aba21aa0:[()=>n.e(742).then(n.t.bind(n,7093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",7093],ac60d37c:[()=>n.e(156).then(n.bind(n,5208)),"@site/docs/README/det04_doc.md",5208],b9bd2c8a:[()=>n.e(50).then(n.bind(n,615)),"@site/docs/Classes/Block.md",615],c008dd48:[()=>n.e(446).then(n.bind(n,3383)),"@site/docs/Detectors/msg-value-in-for-loop.md",3383],c4f5d8e4:[()=>Promise.all([n.e(869),n.e(634)]).then(n.bind(n,3321)),"@site/src/pages/index.js",3321],df5b53bc:[()=>n.e(421).then(n.bind(n,6344)),"@site/docs/Classes/classesIndex.md",6344],e6bcf343:[()=>n.e(769).then(n.bind(n,266)),"@site/docs/README/det02_doc.md",266],ee456a43:[()=>n.e(808).then(n.bind(n,1636)),"@site/docs/Classes/Enclosing.md",1636],f11328d7:[()=>n.e(221).then(n.bind(n,1143)),"@site/docs/Detectors/transfer-from.md",1143],f1c56182:[()=>n.e(829).then(n.bind(n,9036)),"@site/docs/Detectors/incorrect-exp.md",9036],f4dff024:[()=>n.e(351).then(n.bind(n,2207)),"@site/docs/Detectors/divide-before-multiply.md",2207]};var l=n(6070);function s(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,l.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,l.jsx)("p",{children:String(t)}),(0,l.jsx)("div",{children:(0,l.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,l.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,l.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,l.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,l.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(4001),u=n(9334);function d(e,t){if("*"===e)return o()({loading:s,loader:()=>n.e(451).then(n.bind(n,6451)),modules:["@theme/NotFound"],webpack:()=>[6451],render(e,t){const n=e.default;return(0,l.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,l.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],d={},p=[],f=[],m=(0,c.A)(r);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),o().Map({loading:s,loader:d,modules:p,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let i=o;const l=n.split(".");l.slice(0,-1).forEach((e=>{i=i[e]})),i[l[l.length-1]]=a}));const a=o.__comp;delete o.__comp;const i=o.__context;delete o.__context;const s=o.__props;return delete o.__props,(0,l.jsx)(u.W,{value:i,children:(0,l.jsx)(a,{...o,...s,...n})})}})}const p=[{path:"/CyScout/markdown-page",component:d("/CyScout/markdown-page","b3c"),exact:!0},{path:"/CyScout/docs",component:d("/CyScout/docs","657"),routes:[{path:"/CyScout/docs",component:d("/CyScout/docs","fc8"),routes:[{path:"/CyScout/docs",component:d("/CyScout/docs","0a5"),routes:[{path:"/CyScout/docs/Classes/Access",component:d("/CyScout/docs/Classes/Access","5ec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/BasicBlock",component:d("/CyScout/docs/Classes/BasicBlock","eb4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/Block",component:d("/CyScout/docs/Classes/Block","f79"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/Call",component:d("/CyScout/docs/Classes/Call","c23"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/classesIndex",component:d("/CyScout/docs/Classes/classesIndex","642"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/ControlFlowGraph",component:d("/CyScout/docs/Classes/ControlFlowGraph","5d9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/Enclosing",component:d("/CyScout/docs/Classes/Enclosing","83d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/Function",component:d("/CyScout/docs/Classes/Function","a23"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/Specifier",component:d("/CyScout/docs/Classes/Specifier","d73"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/SubBasicBlock",component:d("/CyScout/docs/Classes/SubBasicBlock","585"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Classes/Variable",component:d("/CyScout/docs/Classes/Variable","440"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/",component:d("/CyScout/docs/Detectors/","ff9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/divide-before-multiply",component:d("/CyScout/docs/Detectors/divide-before-multiply","31c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/incorrect-exp",component:d("/CyScout/docs/Detectors/incorrect-exp","ece"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/incorrect-shift",component:d("/CyScout/docs/Detectors/incorrect-shift","7bc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/is-unreachable",component:d("/CyScout/docs/Detectors/is-unreachable","06e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/msg-value-in-for-loop",component:d("/CyScout/docs/Detectors/msg-value-in-for-loop","339"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/transfer-from",component:d("/CyScout/docs/Detectors/transfer-from","f21"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/unchecked-send",component:d("/CyScout/docs/Detectors/unchecked-send","150"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/Detectors/unprotected-self-destruct",component:d("/CyScout/docs/Detectors/unprotected-self-destruct","fa8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/README/",component:d("/CyScout/docs/README/","d9a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/README/det01_doc",component:d("/CyScout/docs/README/det01_doc","f7c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/README/det02_doc",component:d("/CyScout/docs/README/det02_doc","4f0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/README/det03_doc",component:d("/CyScout/docs/README/det03_doc","b16"),exact:!0,sidebar:"tutorialSidebar"},{path:"/CyScout/docs/README/det04_doc",component:d("/CyScout/docs/README/det04_doc","98f"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"/CyScout/",component:d("/CyScout/","3ee"),exact:!0},{path:"*",component:d("*")}]},9749:(e,t,n)=>{"use strict";n.d(t,{o:()=>a,x:()=>i});var r=n(758),o=n(6070);const a=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},6535:(e,t,n)=>{"use strict";var r=n(758),o=n(9576),a=n(248),i=n(1742),l=n(4784),s=n(1177);const c=[n(6803),n(3946),n(6268),n(1644)];var u=n(6452),d=n(5557),p=n(389),f=n(6070);function m(e){let{children:t}=e;return(0,f.jsx)(f.Fragment,{children:t})}var h=n(9668),g=n(9970),y=n(5153),b=n(2433),v=n(4794),w=n(630),k=n(5108);var S=n(101),x=n(8301);function C(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,g.A)(),r=(0,w.o)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,f.jsxs)(h.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,g.A)(),{pathname:r}=(0,d.zy)();return e+(0,S.Ks)((0,y.Ay)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,f.jsxs)(h.A,{children:[(0,f.jsx)("meta",{property:"og:url",content:o}),(0,f.jsx)("link",{rel:"canonical",href:o})]})}function _(){const{i18n:{currentLocale:e}}=(0,g.A)(),{metadata:t,image:n}=(0,b.p)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(h.A,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:k.w})]}),n&&(0,f.jsx)(v.be,{image:n}),(0,f.jsx)(E,{}),(0,f.jsx)(C,{}),(0,f.jsx)(x.A,{tag:"default",locale:e}),(0,f.jsx)(h.A,{children:t.map(((e,t)=>(0,f.jsx)("meta",{...e},t)))})]})}const A=new Map;var T=n(9749),j=n(6888),R=n(5461);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const P=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,R.A)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),N("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function D(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,p.u)(u.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class L extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.A.canUseDOM?N("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=N("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),D(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(P,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(d.qh,{location:t,render:()=>e})})}}const O=L,I="__docusaurus-base-url-issue-banner-suggestion-container";function M(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '__docusaurus-base-url-issue-banner-container';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{let{route:t}=e;return!0===t.exact})))return A.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return A.set(e.pathname,t),{...e,pathname:t}}((0,d.zy)());return(0,f.jsx)(O,{location:e,children:H})}function V(){return(0,f.jsx)($.A,{children:(0,f.jsx)(j.l,{children:(0,f.jsxs)(T.x,{children:[(0,f.jsxs)(m,{children:[(0,f.jsx)(B,{}),(0,f.jsx)(_,{}),(0,f.jsx)(z,{}),(0,f.jsx)(G,{})]}),(0,f.jsx)(q,{})]})})})}var W=n(4054);const Q=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var K=n(4001);const Y=new Set,Z=new Set,X=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,J={prefetch:e=>{if(!(e=>!X()&&!Z.has(e)&&!Y.has(e))(e))return!1;Y.add(e);const t=(0,p.u)(u.A,e).flatMap((e=>{return t=e.route.path,Object.entries(W).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,K.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Q(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!X()&&!Z.has(e))(e)&&(Z.add(e),D(e))},ee=Object.freeze(J);function te(e){let{children:t}=e;return"hash"===l.default.future.experimental_router?(0,f.jsx)(i.I9,{children:t}):(0,f.jsx)(i.Kd,{children:t})}const ne=Boolean(!0);if(s.A.canUseDOM){window.docusaurus=ee;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(a.vd,{children:(0,f.jsx)(te,{children:(0,f.jsx)(V,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(ne)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};D(window.location.pathname).then((()=>{(0,r.startTransition)(i)}))}},6888:(e,t,n)=>{"use strict";n.d(t,{o:()=>d,l:()=>p});var r=n(758),o=n(4784);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/CyScout/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/CyScout/docs","mainDocId":"Classes/Access","docs":[{"id":"Classes/Access","path":"/CyScout/docs/Classes/Access","sidebar":"tutorialSidebar"},{"id":"Classes/BasicBlock","path":"/CyScout/docs/Classes/BasicBlock","sidebar":"tutorialSidebar"},{"id":"Classes/Block","path":"/CyScout/docs/Classes/Block","sidebar":"tutorialSidebar"},{"id":"Classes/Call","path":"/CyScout/docs/Classes/Call","sidebar":"tutorialSidebar"},{"id":"Classes/classesIndex","path":"/CyScout/docs/Classes/classesIndex","sidebar":"tutorialSidebar"},{"id":"Classes/ControlFlowGraph","path":"/CyScout/docs/Classes/ControlFlowGraph","sidebar":"tutorialSidebar"},{"id":"Classes/Enclosing","path":"/CyScout/docs/Classes/Enclosing","sidebar":"tutorialSidebar"},{"id":"Classes/Function","path":"/CyScout/docs/Classes/Function","sidebar":"tutorialSidebar"},{"id":"Classes/Specifier","path":"/CyScout/docs/Classes/Specifier","sidebar":"tutorialSidebar"},{"id":"Classes/SubBasicBlock","path":"/CyScout/docs/Classes/SubBasicBlock","sidebar":"tutorialSidebar"},{"id":"Classes/Variable","path":"/CyScout/docs/Classes/Variable","sidebar":"tutorialSidebar"},{"id":"Detectors/divide-before-multiply","path":"/CyScout/docs/Detectors/divide-before-multiply","sidebar":"tutorialSidebar"},{"id":"Detectors/incorrect-exp","path":"/CyScout/docs/Detectors/incorrect-exp","sidebar":"tutorialSidebar"},{"id":"Detectors/incorrect-shift","path":"/CyScout/docs/Detectors/incorrect-shift","sidebar":"tutorialSidebar"},{"id":"Detectors/index","path":"/CyScout/docs/Detectors/","sidebar":"tutorialSidebar"},{"id":"Detectors/is-unreachable","path":"/CyScout/docs/Detectors/is-unreachable","sidebar":"tutorialSidebar"},{"id":"Detectors/msg-value-in-for-loop","path":"/CyScout/docs/Detectors/msg-value-in-for-loop","sidebar":"tutorialSidebar"},{"id":"Detectors/transfer-from","path":"/CyScout/docs/Detectors/transfer-from","sidebar":"tutorialSidebar"},{"id":"Detectors/unchecked-send","path":"/CyScout/docs/Detectors/unchecked-send","sidebar":"tutorialSidebar"},{"id":"Detectors/unprotected-self-destruct","path":"/CyScout/docs/Detectors/unprotected-self-destruct","sidebar":"tutorialSidebar"},{"id":"README/det01_doc","path":"/CyScout/docs/README/det01_doc","sidebar":"tutorialSidebar"},{"id":"README/det02_doc","path":"/CyScout/docs/README/det02_doc","sidebar":"tutorialSidebar"},{"id":"README/det03_doc","path":"/CyScout/docs/README/det03_doc","sidebar":"tutorialSidebar"},{"id":"README/det04_doc","path":"/CyScout/docs/README/det04_doc","sidebar":"tutorialSidebar"},{"id":"README/readme","path":"/CyScout/docs/README/","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/CyScout/docs/Classes/Access","label":"Classes/Access"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(2654);const s=JSON.parse('{"docusaurusVersion":"3.5.2","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.5.2"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.5.2"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.5.2"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.5.2"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.5.2"}}}');var c=n(6070);const u={siteConfig:o.default,siteMetadata:s,globalData:a,i18n:i,codeTranslations:l},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},7062:(e,t,n)=>{"use strict";n.d(t,{A:()=>h});var r=n(758),o=n(1177),a=n(9668),i=n(101),l=n(1229),s=n(9334),c=n(6070);function u(e){let{error:t,tryAgain:n}=e;return(0,c.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,c.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,c.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,c.jsx)(d,{error:t})]})}function d(e){let{error:t}=e;const n=(0,i.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,c.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function p(e){let{children:t}=e;return(0,c.jsx)(s.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function f(e){let{error:t,tryAgain:n}=e;return(0,c.jsx)(p,{children:(0,c.jsxs)(h,{fallback:()=>(0,c.jsx)(u,{error:t,tryAgain:n}),children:[(0,c.jsx)(a.A,{children:(0,c.jsx)("title",{children:"Page Error"})}),(0,c.jsx)(l.A,{children:(0,c.jsx)(u,{error:t,tryAgain:n})})]})})}const m=e=>(0,c.jsx)(f,{...e});class h extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??m)(e)}return e??null}}},1177:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},9668:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(758);var r=n(248),o=n(6070);function a(e){return(0,o.jsx)(r.mg,{...e})}},3166:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var r=n(758),o=n(1742),a=n(101),i=n(9970),l=n(5222),s=n(1177),c=n(7539),u=n(5153),d=n(6070);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":g,autoAddBaseUrl:y=!0,...b}=e;const{siteConfig:v}=(0,i.A)(),{trailingSlash:w,baseUrl:k}=v,S=v.future.experimental_router,{withBaseUrl:x}=(0,u.hH)(),C=(0,c.A)(),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>E.current));const _=p||f;const A=(0,l.A)(_),T=_?.replace("pathname://","");let j=void 0!==T?(R=T,y&&(e=>e.startsWith("/"))(R)?x(R):R):void 0;var R;"hash"===S&&j?.startsWith("./")&&(j=j?.slice(1)),j&&A&&(j=(0,a.Ks)(j,{trailingSlash:w,baseUrl:k}));const N=(0,r.useRef)(!1),P=n?o.k2:o.N_,D=s.A.canUseIntersectionObserver,L=(0,r.useRef)(),O=()=>{N.current||null==j||(window.docusaurus.preload(j),N.current=!0)};(0,r.useEffect)((()=>(!D&&A&&s.A.canUseDOM&&null!=j&&window.docusaurus.prefetch(j),()=>{D&&L.current&&L.current.disconnect()})),[L,j,D,A]);const I=j?.startsWith("#")??!1,M=!b.target||"_self"===b.target,F=!j||!A||!M||I&&"hash"!==S;g||!I&&F||C.collectLink(j),b.id&&C.collectAnchor(b.id);const z={};return F?(0,d.jsx)("a",{ref:E,href:j,..._&&!A&&{target:"_blank",rel:"noopener noreferrer"},...b,...z}):(0,d.jsx)(P,{...b,onMouseEnter:O,onTouchStart:O,innerRef:e=>{E.current=e,D&&e&&A&&(L.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(L.current.unobserve(e),L.current.disconnect(),null!=j&&window.docusaurus.prefetch(j))}))})),L.current.observe(e))},to:j,...n&&{isActive:h,activeClassName:m},...z})}const f=r.forwardRef(p)},8986:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r=()=>null},8618:(e,t,n)=>{"use strict";n.d(t,{A:()=>c,T:()=>s});var r=n(758),o=n(6070);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(2654);function l(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return a(l({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=l({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(i,r)})}},8465:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},5222:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>o,z:()=>r})},5153:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>l,hH:()=>i});var r=n(758),o=n(9970),a=n(5222);function i(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,i=e.future.experimental_router,l=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:o=!1,absolute:i=!1}={},router:l}=e;if(!r||r.startsWith("#")||(0,a.z)(r))return r;if("hash"===l)return r.startsWith("/")?`.${r}`:`./${r}`;if(o)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const s=r.startsWith(n)?r:n+r.replace(/^\//,"");return i?t+s:s}({siteUrl:n,baseUrl:t,url:e,options:r,router:i})),[n,t,i]);return{withBaseUrl:l}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},7539:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(758);n(6070);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,r.useContext)(o);function i(){return a()}},9970:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(758),o=n(6888);function a(){return(0,r.useContext)(o.o)}},6919:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(758),o=n(9749);function a(){return(0,r.useContext)(o.o)}},5461:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(758);const o=n(1177).A.canUseDOM?r.useLayoutEffect:r.useEffect},4001:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,i]=n;const l=o?`${o}.${a}`:a;r(i)?e(i,l):t[l]=i}))}(e),t}},9334:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>a});var r=n(758),o=n(6070);const a=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(a),l=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,o.jsx)(a.Provider,{value:l,children:t})}},6257:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>g,g1:()=>b});var r=n(758),o=n(4796),a=n(8465),i=n(2433),l=n(3591),s=n(2187),c=n(6070);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,l.Wf)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,l.Wf)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,l.Wf)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,o.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,l]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return(0,c.jsx)(f.Provider,{value:n,children:t})}function g(e){let{children:t}=e;return(0,c.jsx)(h,{children:t})}function y(){const e=(0,r.useContext)(f);if(!e)throw new s.dV("DocsPreferredVersionContextProvider");return e}function b(e){void 0===e&&(e=a.W);const t=(0,o.ht)(e),[n,i]=y(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1904:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,t:()=>c});var r=n(758),o=n(2187),a=n(6070);const i=Symbol("EmptyContext"),l=r.createContext(i);function s(e){let{children:t,name:n,items:o}=e;const i=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(l.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(l);if(e===i)throw new o.dV("DocsSidebarProvider");return e}},8483:(e,t,n)=>{"use strict";n.d(t,{Nr:()=>p,w8:()=>h,B5:()=>x,Vd:()=>w,QB:()=>S,fW:()=>k,OF:()=>v,Y:()=>y});var r=n(758),o=n(5557),a=n(389),i=n(4796),l=n(2488);function s(e){return Array.from(new Set(e))}var c=n(6257),u=n(1952),d=n(1904);function p(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=p(t);if(e)return e}}(e):void 0:e.href}const f=(e,t)=>void 0!==e&&(0,l.ys)(e,t),m=(e,t)=>e.some((e=>h(e,t)));function h(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||m(e.items,t))}function g(e,t){switch(e.type){case"category":return h(e,t)||e.items.some((e=>g(e,t)));case"link":return!e.unlisted||h(e,t);default:return!0}}function y(e,t){return(0,r.useMemo)((()=>e.filter((e=>g(e,t)))),[e,t])}function b(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,l.ys)(a.href,n)||e(a.items))||"link"===a.type&&(0,l.ys)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function v(){const e=(0,d.t)(),{pathname:t}=(0,o.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?b({sidebarItems:e.items,pathname:t}):null}function w(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,c.g1)(e),o=(0,i.r7)(e);return(0,r.useMemo)((()=>s([t,n,o].filter(Boolean))),[t,n,o])}function k(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function S(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${s(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function x(e){let{route:t}=e;const n=(0,o.zy)(),r=(0,u.r)(),i=t.routes,l=i.find((e=>(0,o.B6)(n.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?r.docsSidebars[s]:void 0;return{docElement:(0,a.v)(i),sidebarName:s,sidebarItems:c}}},1952:(e,t,n)=>{"use strict";n.d(t,{n:()=>l,r:()=>s});var r=n(758),o=n(2187),a=n(6070);const i=r.createContext(null);function l(e){let{children:t,version:n}=e;return(0,a.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(null===e)throw new o.dV("DocsVersionProvider");return e}},4796:(e,t,n)=>{"use strict";n.d(t,{zK:()=>h,vT:()=>p,Gy:()=>u,HW:()=>g,ht:()=>d,r7:()=>m,jh:()=>f});var r=n(5557),o=n(9970),a=n(8465);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),o=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>{try{return function(e,t,n){void 0===t&&(t=a.W),void 0===n&&(n={});const r=i(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function h(e){const t=d(e),{pathname:n}=(0,r.zy)();return s(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},4355:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(8744),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},3946:(e,t,n)=>{"use strict";var r=n(5371),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(1274),n(7333)(`./prism-${e}`)})),delete globalThis.Prism}(r.My)},1523:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(758);var r=n(3526),o=n(8618),a=n(2433),i=n(3166),l=n(7539);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_qeIy",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_TI2v"};var c=n(6070);function u(e){let{as:t,id:n,...u}=e;const d=(0,l.A)(),{navbar:{hideOnScroll:p}}=(0,a.p)();if("h1"===t||!n)return(0,c.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const f=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,c.jsxs)(t,{...u,className:(0,r.A)("anchor",p?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,c.jsx)(i.A,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},6187:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(758);const r={iconExternalLink:"iconExternalLink_iQji"};var o=n(6070);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},1229:(e,t,n)=>{"use strict";n.d(t,{A:()=>ft});var r=n(758),o=n(3526),a=n(7062),i=n(4794),l=n(5557),s=n(8618),c=n(2767),u=n(6070);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,l.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,s.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(5074),y=n(5108);const b={skipToContent:"skipToContent_IipK"};function v(){return(0,u.jsx)(h,{className:b.skipToContent})}var w=n(2433),k=n(2358);function S(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const x={closeButton:"closeButton_zzJf"};function C(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",x.closeButton,e.className),children:(0,u.jsx)(S,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_lMoF"};function _(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const A={announcementBar:"announcementBar_kOc5",announcementBarPlaceholder:"announcementBarPlaceholder_TyKa",announcementBarClose:"announcementBarClose_ImJ9",announcementBarContent:"announcementBarContent_Iu6V"};function T(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,k.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:A.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:A.announcementBarPlaceholder}),(0,u.jsx)(_,{className:A.announcementBarContent}),a&&(0,u.jsx)(C,{onClick:n,className:A.announcementBarClose})]})}var j=n(8209),R=n(3841);var N=n(2187),P=n(3303);const D=r.createContext(null);function L(e){let{children:t}=e;const n=function(){const e=(0,j.M)(),t=(0,P.YL)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,N.ZC)(a);return(0,r.useEffect)((()=>{a&&!i&&o(!0)}),[a,i]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(D.Provider,{value:n,children:t})}function O(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function I(){const e=(0,r.useContext)(D);if(!e)throw new N.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,P.YL)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:O(a)})),[o,a,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=I();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var F=n(5898),z=n(6919);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_DITL",toggleButton:"toggleButton_bazi",darkToggleIcon:"darkToggleIcon_uFh4",lightToggleIcon:"lightToggleIcon_j6C1",toggleButtonDisabled:"toggleButtonDisabled_IzIM"};function q(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const i=(0,z.A)(),l=(0,s.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,s.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,s.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.A)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.A)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!i,title:l,"aria-label":l,"aria-live":"polite",children:[(0,u.jsx)(B,{className:(0,o.A)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,o.A)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(q),G={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_am3Y"};function V(e){let{className:t}=e;const n=(0,w.p)().navbar.style,r=(0,w.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,F.G)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?G.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var W=n(1479);function Q(){return(0,u.jsx)(W.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,j.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(S,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(Q,{}),(0,u.jsx)(V,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Z=n(3166),X=n(5153),J=n(5222);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(6187);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:i,isDropdownLink:l,prependBaseUrlToHref:s,...c}=e;const d=(0,X.Ay)(r),p=(0,X.Ay)(t),f=(0,X.Ay)(o,{forcePrependBaseUrl:!0}),m=a&&o&&!(0,J.A)(o),h=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,m&&(0,u.jsx)(te.A,{...l&&{width:12,height:12}})]})};return o?(0,u.jsx)(Z.A,{href:s?f:o,...c,...h}):(0,u.jsx)(Z.A,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},...c,...h})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,u.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.A)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(3617),le=n(2488),se=n(9970);const ce="dropdownNavbarItemMobile_yTwS";function ue(e,t){return e.some((e=>function(e,t){return!!(0,le.ys)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:a,onClick:i,...l}=e;const s=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{s.current&&!s.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[s]),(0,u.jsxs)("div",{ref:s,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:l.to?void 0:"#",className:(0,o.A)("navbar__link",a),...l,onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:l.children??l.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Ee,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:a,onClick:i,...s}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,se.A)(),{pathname:t}=(0,l.zy)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[c,d,m]),(0,u.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.A)(ce,"menu__link menu__link--sublist menu__link--sublist-caret",n),...s,onClick:e=>{e.preventDefault(),f()},children:s.children??s.label}),(0,u.jsx)(ie.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(Ee,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var me=n(630);function he(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const ge="iconLanguage_V5yt";var ye=n(8986);const be={navbarSearchContainer:"navbarSearchContainer_nbxA"};function ve(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.A)(n,be.navbarSearchContainer),children:t})}var we=n(4796),ke=n(8483);var Se=n(6257);function xe(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const Ce={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,se.A)(),p=(0,me.o)(),{search:f,hash:m}=(0,l.zy)(),h=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}${o}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],g=t?(0,s.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(fe,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:ge}),g]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(ve,{className:n,children:(0,u.jsx)(ye.A,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const i=a?"li":"div";return(0,u.jsx)(i,{className:(0,o.A)({navbar__item:!r&&!a,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,we.zK)(r),i=(0,ke.QB)(t,r),l=a?.path===i?.path;return null===i||i.unlisted&&!l?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>l||!!a?.sidebar&&a.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,we.zK)(r),i=(0,ke.fW)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const a=(0,ke.Vd)(r)[0],i=t??a.label,l=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:i,to:l})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:a,...i}=e;const{search:c,hash:d}=(0,l.zy)(),p=(0,we.zK)(n),f=(0,we.jh)(n),{savePreferredVersionName:m}=(0,Se.g1)(n),h=[...o,...f.map((function(e){const t=xe(e,p);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>m(e.name)}})),...a],g=(0,ke.Vd)(n)[0],y=t&&h.length>1?(0,s.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):g.label,b=t&&h.length>1?void 0:xe(g,p).path;return h.length<=1?(0,u.jsx)(ae,{...i,mobile:t,label:y,to:b,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...i,mobile:t,label:y,to:b,items:h,isActive:r?()=>!1:void 0})}};function Ee(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ce[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function _e(){const e=(0,j.M)(),t=(0,w.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Ee,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ae(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(s.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Te(){const e=0===(0,w.p)().navbar.items.length,t=I();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ae,{onClick:()=>t.hide()}),t.content]})}function je(){const e=(0,j.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(_e,{}),secondaryMenu:(0,u.jsx)(Te,{})}):null}const Re={navbarHideable:"navbarHideable_RAkV",navbarHidden:"navbarHidden_VQZ2"};function Ne(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function Pe(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.p)(),i=(0,j.M)(),{navbarRef:l,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,R.Mq)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:l,"aria-label":(0,s.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[Re.navbarHideable,!d&&Re.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ne,{onClick:i.toggle}),(0,u.jsx)(je,{})]})}var De=n(101);const Le={errorBoundaryError:"errorBoundaryError_zJEu",errorBoundaryFallback:"errorBoundaryFallback_APqz"};function Oe(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(s.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function Ie(e){let{error:t}=e;const n=(0,De.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Le.errorBoundaryError,children:n})}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Fe="right";function ze(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function Be(){const{toggle:e,shown:t}=(0,j.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,s.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(ze,{})})}const $e={colorModeToggle:"colorModeToggle_bvw4"};function Ue(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Me,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Ee,{...e})},t)))})}function qe(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function He(){const e=(0,j.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Fe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(qe,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(Be,{}),(0,u.jsx)(Q,{}),(0,u.jsx)(Ue,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ue,{items:r}),(0,u.jsx)(V,{className:$e.colorModeToggle}),!o&&(0,u.jsx)(ve,{children:(0,u.jsx)(ye.A,{})})]})})}function Ge(){return(0,u.jsx)(Pe,{children:(0,u.jsx)(He,{})})}function Ve(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...i}=t,l=(0,X.Ay)(n),s=(0,X.Ay)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Z.A,{className:"footer__link-item",...r?{href:a?s:r}:{to:l},...i,children:[o,r&&!(0,J.A)(r)&&(0,u.jsx)(te.A,{})]})}function We(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(Ve,{item:t})},t.href??t.to)}function Qe(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(We,{item:e},t)))})]})}function Ke(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(Qe,{column:e},t)))})}function Ye(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function Ze(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(Ve,{item:t})}function Xe(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(Ze,{item:e}),t.length!==n+1&&(0,u.jsx)(Ye,{})]},n)))})})}function Je(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(Ke,{columns:t}):(0,u.jsx)(Xe,{links:t})}var et=n(1131);const tt="footerLogoLink_HaW_";function nt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(et.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function rt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Z.A,{href:t.href,className:tt,target:t.target,children:(0,u.jsx)(nt,{logo:t})}):(0,u.jsx)(nt,{logo:t})}function ot(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:r,copyright:a}=e;return(0,u.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||a)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),a]})]})})}function it(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(at,{style:o,links:n&&n.length>0&&(0,u.jsx)(Je,{links:n}),logo:r&&(0,u.jsx)(rt,{logo:r}),copyright:t&&(0,u.jsx)(ot,{copyright:t})})}const lt=r.memo(it),st=(0,N.fM)([F.a,k.o,R.Tv,Se.VQ,i.Jx,function(e){let{children:t}=e;return(0,u.jsx)(P.y_,{children:(0,u.jsx)(j.e,{children:(0,u.jsx)(L,{children:t})})})}]);function ct(e){let{children:t}=e;return(0,u.jsx)(st,{children:t})}var ut=n(1523);function dt(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(ut.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(s.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Oe,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Ie,{error:t})})]})})})}const pt={mainWrapper:"mainWrapper_pOYi"};function ft(e){const{children:t,noFooter:n,wrapperClassName:r,title:l,description:s}=e;return(0,y.J)(),(0,u.jsxs)(ct,{children:[(0,u.jsx)(i.be,{title:l,description:s}),(0,u.jsx)(v,{}),(0,u.jsx)(T,{}),(0,u.jsx)(Ge,{}),(0,u.jsx)("div",{id:d,className:(0,o.A)(g.G.wrapper.main,pt.mainWrapper,r),children:(0,u.jsx)(a.A,{fallback:e=>(0,u.jsx)(dt,{...e}),children:t})}),!n&&(0,u.jsx)(lt,{})]})}},1479:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(758);var r=n(3166),o=n(5153),a=n(9970),i=n(2433),l=n(1131),s=n(6070);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Ay)(t.src),dark:(0,o.Ay)(t.srcDark||t.src)},i=(0,s.jsx)(l.A,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,s.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,a.A)(),{navbar:{title:n,logo:l}}=(0,i.p)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,o.Ay)(l?.href||"/"),m=n?"":t,h=l?.alt??m;return(0,s.jsxs)(r.A,{to:f,...p,...l?.target&&{target:l.target},children:[l&&(0,s.jsx)(c,{logo:l,alt:h,imageClassName:u}),null!=n&&(0,s.jsx)("b",{className:d,children:n})]})}},8301:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(758);var r=n(9668),o=n(6070);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return(0,o.jsxs)(r.A,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),i&&(0,o.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},1131:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var r=n(758),o=n(3526),a=n(6919),i=n(5898);const l={themedComponent:"themedComponent_Az_r","themedComponent--light":"themedComponent--light_ik9_","themedComponent--dark":"themedComponent--dark_eDvw"};var s=n(6070);function c(e){let{className:t,children:n}=e;const c=(0,a.A)(),{colorMode:u}=(0,i.G)();return(0,s.jsx)(s.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.A)(t,l.themedComponent,l[`themedComponent--${e}`])});return(0,s.jsx)(r.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,s.jsx)(c,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,s.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},3617:(e,t,n)=>{"use strict";n.d(t,{N:()=>y,u:()=>c});var r=n(758),o=n(1177),a=n(5461),i=n(1298),l=n(6070);const s="ease-in-out";function c(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),a=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,i.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??s}`,height:`${t}px`}}function l(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return p(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function m(e){if(!o.A.canUseDOM)return e?u:d}function h(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:i,className:s,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:a}),(0,l.jsx)(t,{ref:u,style:c?void 0:m(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:s,children:o})}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[s,c]=(0,r.useState)(t);return(0,a.A)((()=>{t||i(!0)}),[t]),(0,a.A)((()=>{o&&c(t)}),[o,t]),o?(0,l.jsx)(h,{...n,collapsed:s}):null}function y(e){let{lazy:t,...n}=e;const r=t?g:h;return(0,l.jsx)(r,{...n})}},2358:(e,t,n)=>{"use strict";n.d(t,{M:()=>h,o:()=>m});var r=n(758),o=n(6919),a=n(3591),i=n(2187),l=n(2433),s=n(6070);const c=(0,a.Wf)("docusaurus.announcement.dismiss"),u=(0,a.Wf)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function m(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.p)(),t=(0,o.A)(),[n,a]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{a(d())}),[]);const i=(0,r.useCallback)((()=>{p(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,s.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5898:(e,t,n)=>{"use strict";n.d(t,{G:()=>y,a:()=>g});var r=n(758),o=n(1177),a=n(2187),i=n(3591),l=n(2433),s=n(6070);const c=r.createContext(void 0),u="theme",d=(0,i.Wf)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,m=e=>o.A.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{d.set(f(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.p)(),[o,a]=(0,r.useState)(m(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(a(t),o&&h(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:i,get isDarkTheme(){return o===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[o,i])}();return(0,s.jsx)(c.Provider,{value:n,children:t})}function y(){const e=(0,r.useContext)(c);if(null==e)throw new a.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},8209:(e,t,n)=>{"use strict";n.d(t,{e:()=>f,M:()=>m});var r=n(758),o=n(3303),a=n(2972),i=n(5557),l=n(2187);function s(e){!function(e){const t=(0,i.W6)(),n=(0,l._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(2433),u=n(6070);const d=r.createContext(void 0);function p(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,c.p)().navbar;return 0===t.length&&!e.component}(),t=(0,a.l)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function f(e){let{children:t}=e;const n=p();return(0,u.jsx)(d.Provider,{value:n,children:t})}function m(){const e=r.useContext(d);if(void 0===e)throw new l.dV("NavbarMobileSidebarProvider");return e}},3303:(e,t,n)=>{"use strict";n.d(t,{GX:()=>c,YL:()=>s,y_:()=>l});var r=n(758),o=n(2187),a=n(6070);const i=r.createContext(null);function l(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,a.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const a=(0,r.useContext)(i);if(!a)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,l]=a,s=(0,o.Be)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},5108:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>a});var r=n(758);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},2972:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(758),o=n(1177);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,l]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){l(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?a.desktop:a.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},5074:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},1298:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},4794:(e,t,n)=>{"use strict";n.d(t,{e3:()=>f,be:()=>d,Jx:()=>m});var r=n(758),o=n(3526),a=n(9668),i=n(9334);function l(){const e=r.useContext(i.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(5153),c=n(9970);var u=n(6070);function d(e){let{title:t,description:n,keywords:r,image:o,children:i}=e;const l=function(e){const{siteConfig:t}=(0,c.A)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.hH)(),p=o?d(o,{absolute:!0}):void 0;return(0,u.jsxs)(a.A,{children:[t&&(0,u.jsx)("title",{children:l}),t&&(0,u.jsx)("meta",{property:"og:title",content:l}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(p),l=(0,o.A)(i,t);return(0,u.jsxs)(p.Provider,{value:l,children:[(0,u.jsx)(a.A,{children:(0,u.jsx)("html",{className:l})}),n]})}function m(e){let{children:t}=e;const n=l(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,o.A)(r,a),children:t})}},2187:(e,t,n)=>{"use strict";n.d(t,{Be:()=>c,ZC:()=>l,_q:()=>i,dV:()=>s,fM:()=>u});var r=n(758),o=n(5461),a=n(6070);function i(e){const t=(0,r.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function l(e){const t=(0,r.useRef)();return(0,o.A)((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},2488:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>l,ys:()=>i});var r=n(758),o=n(6452),a=n(9970);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,a.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.A,baseUrl:e})),[e])}},3841:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>p,Tv:()=>c,gk:()=>f});var r=n(758),o=n(1177),a=n(6919),i=(n(5461),n(2187)),l=n(6070);const s=r.createContext(void 0);function c(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(s.Provider,{value:n,children:t})}function u(){const e=(0,r.useContext)(s);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const d=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function p(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),o=(0,r.useRef)(d()),a=(0,i._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,a.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&ot&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3591:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>c});n(758);const r=JSON.parse('{"N":"localStorage","M":""}'),o=r.N;function a(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function i(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){const n=`${e}${r.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const o=i(t?.persistence);return null===o?s:{get:()=>{try{return o.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=o.getItem(n);o.setItem(n,e),a({key:n,oldValue:t,newValue:e,storage:o})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=o.getItem(n);o.removeItem(n),a({key:n,oldValue:e,newValue:null,storage:o})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===o&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}},630:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(9970),o=n(5557),a=n(101);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.A)(),{pathname:s}=(0,o.zy)(),c=(0,a.Ks)(s,{trailingSlash:n,baseUrl:e}),u=l===i?e:e.replace(`/${l}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},2767:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(758),o=n(5557),a=n(2187);function i(e){const t=(0,o.zy)(),n=(0,a.ZC)(t),i=(0,a._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},2433:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(9970);function o(){return(0,r.A)().siteConfig.themeConfig}},8248:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),l="/"===i||i===r?i:(s=i,c=n,c?o(s):a(s));var s,c;return e.replace(i,l)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=a;const r=n(8687);function o(e){return e.endsWith("/")?e:`${e}/`}function a(e){return(0,r.removeSuffix)(e,"/")}},7982:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},101:(e,t,n)=>{"use strict";t.rA=t.Ks=void 0;const r=n(3460);var o=n(8248);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(o).default}});var a=n(8687);var i=n(7982);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},8687:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},3332:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>_,yJ:()=>f,sC:()=>T,AO:()=>p});var r=n(8762);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r=0;p--){var f=i[p];"."===f?a(i,p):".."===f?(a(i,p),d++):d&&(a(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(5385);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.A)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,h(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(5959),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||o}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=f(n);o&&o!==m&&e(t,o,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),g=0;g{"use strict";e.exports=function(e,t,n,r,o,a,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,a,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5526:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},6803:(e,t,n)=>{"use strict";n.r(t)},1644:(e,t,n)=>{"use strict";n.r(t)},8744:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function o(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),c=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){s(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),l=e?"-100":a(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},4785:(e,t,n)=>{var r=n(5526);e.exports=m,e.exports.parse=a,e.exports.compile=function(e,t){return s(a(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=f;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,l=0,s="",c=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(l,f),l=f+d.length,p)s+=p[1];else{var m=e[l],h=n[2],g=n[3],y=n[4],b=n[5],v=n[6],w=n[7];s&&(r.push(s),s="");var k=null!=h&&null!=m&&m!==h,S="+"===v||"*"===v,x="?"===v||"*"===v,C=h||c,E=y||b,_=h||("string"==typeof r[r.length-1]?r[r.length-1]:"");r.push({name:g||a++,prefix:h||"",delimiter:C,optional:x,repeat:S,partial:k,asterisk:!!w,pattern:E?u(E):w?".*":i(C,_)})}}return l-1?"[^"+c(e)+"]+?":c(t)+"|(?:(?!"+c(t)+")[^"+c(e)+"])+?"}function l(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function s(e,t){for(var n=new Array(e.length),o=0;o{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},6532:(e,t,n)=>{const r=n(9227),o=n(9670),a=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(7507).resolve(t)],delete Prism.languages[e],n(7507)(t),a.add(e)}))}i.silent=!1,e.exports=i},1274:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,l=i.length;-1!==n.code.indexOf(o=t(r,l));)++l;return i[l]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=a.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=a[o],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++o;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),y=p.substring(m+f.length),b=[];h&&b.push.apply(b,i([h])),b.push(g),y&&b.push.apply(b,i([y])),"string"==typeof c?l.splice.apply(l,[s,1].concat(b)):c.content=b}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(Prism)},7507:(e,t,n)=>{var r={"./":6532};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=7507},9670:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in o(t,a),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,a.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(a,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var a=r[o];t[o]="string"==typeof a?{title:a}:a}}return t}(a),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var a=e[o];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),m=u;o(m);){for(var h in p={},m){var g=s[h];t(g&&g.modify,(function(e){e in d&&(p[e]=!0)}))}for(var y in d)if(!(y in u))for(var b in f(y))if(b in u){p[y]=!0;break}for(var v in m=p)u[v]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var a=o?o.series:void 0,i=o?o.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var o,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)o=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));a?o=a(p,(function(){return r(e)})):r(e)}return l[e]=o}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},6186:(e,t,n)=>{"use strict";var r=n(2985);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},2736:(e,t,n)=>{e.exports=n(6186)()},2985:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},9481:(e,t,n)=>{"use strict";var r=n(758),o=n(1896);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n