From b2dd6e2ce93adf42fb7a8ba08c2e8551fa64e023 Mon Sep 17 00:00:00 2001 From: behnazh-w Date: Fri, 29 May 2026 07:32:28 +1000 Subject: [PATCH 1/2] chore(deps): update go dependencies Signed-off-by: behnazh-w --- go.mod | 16 +++++++--------- go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/go.mod b/go.mod index 36f40d378..f05de26a0 100644 --- a/go.mod +++ b/go.mod @@ -3,24 +3,22 @@ module github.com/oracle/macaron -go 1.24.0 - -toolchain go1.24.13 +go 1.25.0 require ( - cuelang.org/go v0.15.4 - mvdan.cc/sh/v3 v3.12.0 + cuelang.org/go v0.16.1 + mvdan.cc/sh/v3 v3.13.1 ) require ( github.com/cockroachdb/apd/v3 v3.2.1 // indirect - github.com/emicklei/proto v1.14.2 // indirect + github.com/emicklei/proto v1.14.3 // indirect github.com/google/uuid v1.6.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91 // indirect + github.com/protocolbuffers/txtpbfmt v0.0.0-20260217160748-a481f6a22f94 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.46.0 // indirect - golang.org/x/text v0.30.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/text v0.35.0 // indirect google.golang.org/protobuf v1.33.0 // indirect ) diff --git a/go.sum b/go.sum index 167c82781..f29ad04d1 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ -cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084 h1:4k1yAtPvZJZQTu8DRY8muBo0LHv6TqtrE0AO5n6IPYs= -cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084/go.mod h1:4WWeZNxUO1vRoZWAHIG0KZOd6dA25ypyWuwD3ti0Tdc= -cuelang.org/go v0.15.4 h1:lrkTDhqy8dveHgX1ZLQ6WmgbhD8+rXa0fD25hxEKYhw= -cuelang.org/go v0.15.4/go.mod h1:NYw6n4akZcTjA7QQwJ1/gqWrrhsN4aZwhcAL0jv9rZE= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819 h1:Zh+Ur3OsoWpvALHPLT45nOekHkgOt+IOfutBbPqM17I= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819/go.mod h1:WjmQxb+W6nVNCgj8nXrF24lIz95AHwnSl36tpjDZSU8= +cuelang.org/go v0.16.1 h1:iPN1lHZd2J0hjcr8hfq9PnIGk7VfPkKFfxH4de+m9sE= +cuelang.org/go v0.16.1/go.mod h1:/aW3967FeWC5Hc1cDrN4Z4ICVApdMi83wO5L3uF/1hM= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= -github.com/emicklei/proto v1.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I= -github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/proto v1.14.3 h1:zEhlzNkpP8kN6utonKMzlPfIvy82t5Kb9mufaJxSe1Q= +github.com/emicklei/proto v1.14.3/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -28,28 +28,28 @@ github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJw github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= -github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91 h1:s1LvMaU6mVwoFtbxv/rCZKE7/fwDmDY684FfUe4c1Io= -github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY= +github.com/protocolbuffers/txtpbfmt v0.0.0-20260217160748-a481f6a22f94 h1:2PC6Ql3jipz1KvBlqUHjjk6v4aMwE86mfDu1XMH0LR8= +github.com/protocolbuffers/txtpbfmt v0.0.0-20260217160748-a481f6a22f94/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI= -mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg= +mvdan.cc/sh/v3 v3.13.1 h1:DP3TfgZhDkT7lerUdnp6PTGKyxxzz6T+cOlY/xEvfWk= +mvdan.cc/sh/v3 v3.13.1/go.mod h1:lXJ8SexMvEVcHCoDvAGLZgFJ9Wsm2sulmoNEXGhYZD0= From e869695b0f8d25f268a59146c5880fe1a3716b90 Mon Sep 17 00:00:00 2001 From: behnazh-w Date: Mon, 22 Jun 2026 10:16:20 +1000 Subject: [PATCH 2/2] chore: add implementation for missing pipeall op Signed-off-by: behnazh-w --- .../code_analyzer/dataflow_analysis/bash.py | 134 +++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/src/macaron/code_analyzer/dataflow_analysis/bash.py b/src/macaron/code_analyzer/dataflow_analysis/bash.py index fde8a0e5e..7c6f87fac 100644 --- a/src/macaron/code_analyzer/dataflow_analysis/bash.py +++ b/src/macaron/code_analyzer/dataflow_analysis/bash.py @@ -212,6 +212,27 @@ def with_stdout( self.gha_expr_map_items, ) + def with_stdout_stderr( + self, stdout_scope: core.ContextRef[facts.Scope], stdout_loc: facts.LocationSpecifier + ) -> BashScriptContext: + """Return a modified bash script context with the given stdout and stderr. + + TODO currently stderr is not defined in BashScriptContext, so we cannot support here neither. + Add stderr to BashScriptContext to be able to support it here as well. + """ + return BashScriptContext( + self.outer_context, + self.filesystem, + self.env, + self.func_decls, + self.stdin_scope, + self.stdin_loc, + stdout_scope, + stdout_loc, + self.source_filepath, + self.gha_expr_map_items, + ) + def with_gha_expr_map(self, gha_expr_map: dict[str, str]) -> BashScriptContext: """Return a modified bash script context with GitHub-expression placeholder mappings. @@ -772,7 +793,11 @@ def build_pipe() -> core.Node: return {"default": build_pipe} case bashparser_model.BinCmdOperators.PipeAll.value: - pass + + def build_pipeall() -> core.Node: + return BashPipeAllNode.create(cmd, self.context.get_non_owned()) + + return {"default": build_pipeall} case bashparser_model.BinCmdOperators.AndStmt.value: def build_and() -> core.Node: @@ -1272,6 +1297,113 @@ def create( return BashPipeNode(definition=pipe_cmd, lhs=lhs, rhs=rhs, context=pipe_context) +class BashPipeAllNode(core.ControlFlowGraphNode): + """Control flow node representing a Bash pipe (``|&``) binary command. + + Control flow structure consists of executing the left-hand side, followed by the right-hand side. + A pipe scope and location is introduced to model the piping of the + output from the first command to the input of the second command. Compared to + a normal pipe (``|``), ``|&`` pipes both stdout and stderr (file descriptors 1 and 2) + of the left command into stdin of the right. + """ + + #: Parsed pipe all binary command AST. + definition: bashparser_model.BinaryCmd + #: Left-hand side (first) command. + lhs: BashStatementNode + #: Right-hand side (second) command. + rhs: BashStatementNode + #: Pipe context. + context: core.ContextRef[BashPipeContext] + #: Control flow graph. + _cfg: core.ControlFlowGraph + + def __init__( + self, + definition: bashparser_model.BinaryCmd, + lhs: BashStatementNode, + rhs: BashStatementNode, + context: core.ContextRef[BashPipeContext], + ) -> None: + """Initialize Bash pipe all node. + + Typically, construction should be done via the create function rather than using this constructor directly. + + Parameters + ---------- + definition: bashparser_model.BinaryCmd + Parsed pipe all binary command AST. + lhs: BashStatementNode + Left-hand side (first) command. + rhs: BashStatementNode + Right-hand side (second) command. + context: core.ContextRef[BashPipeContext] + Pipe context. + """ + super().__init__() + self.definition = definition + self.lhs = lhs + self.rhs = rhs + self.context = context + + self._cfg = core.ControlFlowGraph(self.lhs) + self._cfg.add_successor(self.lhs, core.DEFAULT_EXIT, self.rhs) + self._cfg.add_successor(self.rhs, core.DEFAULT_EXIT, core.DEFAULT_EXIT) + + def children(self) -> Iterator[core.Node]: + """Yield the subcommands.""" + yield self.lhs + yield self.rhs + + def get_entry(self) -> core.Node: + """Return the entry node (the lhs node).""" + return self._cfg.get_entry() + + def get_successors(self, node: core.Node, exit_type: core.ExitType) -> set[core.Node | core.ExitType]: + """Return the successor for a given node. + + Returns a propagated early exit of the same type in the case of a BashExit or BashReturn exit type. + """ + if isinstance(exit_type, (BashExit, BashReturn)): + return {exit_type} + return self._cfg.get_successors(node, core.DEFAULT_EXIT) + + def get_exit_state_transfer_filter(self) -> core.StateTransferFilter: + """Return state transfer filter to clear scopes owned by this node after this node exits.""" + return core.ExcludedScopesStateTransferFilter(core.get_owned_scopes(self.context)) + + def get_printable_properties_table(self) -> dict[str, set[tuple[str | None, str]]]: + """Return a properties table containing the line number and scopes.""" + result: dict[str, set[tuple[str | None, str]]] = {} + result["line num (in script)"] = {(None, str(self.definition["Pos"]["Line"]))} + printing.add_context_owned_scopes_to_properties_table(result, self.context) + return result + + @staticmethod + def create( + pipe_cmd: bashparser_model.BinaryCmd, context: core.NonOwningContextRef[BashScriptContext] + ) -> BashPipeAllNode: + """Create Bash pipe all node from pipe binary command AST. + + Parameters + ---------- + pipe_cmd: bashparser_model.BinaryCmd + Parsed pipe binary command AST. + context: core.NonOwningContextRef[BashScriptContext] + Bash script context. + """ + pipe_context = core.OwningContextRef(BashPipeContext.create(context)) + piped_from_context = core.NonOwningContextRef( + context.ref.with_stdout_stderr(pipe_context.ref.pipe_scope.get_non_owned(), pipe_context.ref.pipe_loc) + ) + piped_to_context = core.NonOwningContextRef( + context.ref.with_stdin(pipe_context.ref.pipe_scope.get_non_owned(), pipe_context.ref.pipe_loc) + ) + lhs = BashStatementNode(pipe_cmd["X"], piped_from_context) + rhs = BashStatementNode(pipe_cmd["Y"], piped_to_context) + return BashPipeAllNode(definition=pipe_cmd, lhs=lhs, rhs=rhs, context=pipe_context) + + class BashAndNode(core.ControlFlowGraphNode): """Control flow node representing a Bash AND ("&&") binary command.