Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Changed

- **Behavior change:** `socket_additional_params` now uses shell-style,
space-separated arguments and preserves commas within argument values. A
comma acts as a legacy separator only when it is unquoted and followed by a
hyphen (normally another option). Configurations that used commas as general
separators (for example, `--view,full`) must use a space or `=` instead. Repeat
list-valued flags, such as
`--exclude-paths=tests --exclude-paths=fixtures`.

## [3.4.1] - 2026-10-21

### Changed
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ inputs:
required: false
default: ""
socket_additional_params:
description: "Additional CLI params for 'socket scan reach' (comma or space separated). Also reads SOCKET_ADDITIONAL_PARAMS"
description: "Additional CLI params for 'socket scan reach', using shell-style space separation. Commas in values are preserved; only an unquoted comma followed by a hyphen is a legacy separator. Repeat list-valued flags. Also reads SOCKET_ADDITIONAL_PARAMS."
required: false
default: ""
socket_tier_1_enabled:
Expand Down
29 changes: 27 additions & 2 deletions docs/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -716,11 +716,36 @@ socket-basics --socket-tier1
```

### `--socket-additional-params SOCKET_ADDITIONAL_PARAMS`
Additional CLI params for 'socket scan reach' (comma or space separated).
Additional CLI params for `socket scan reach`, parsed with shell-style quoting.

**Behavior change:** Commas no longer act as general argument separators. Use
spaces or `=` between an option and its value (`--view full` or `--view=full`,
not `--view,full`). Commas inside values stay literal. For compatibility, an
unquoted comma followed by another option still separates arguments, as in
`--view=full,--all`. Quote the complete argument to make that sequence literal,
for example `--label="value, --text"`.

**Example:**
```bash
socket-basics --socket-tier1 --socket-additional-params "--view=full,--all"
socket-basics --socket-tier1 --socket-additional-params "--view=full --all"
```

To exclude directories from Socket Tier 1 manifest discovery and reachability,
repeat `--exclude-paths` for each value. Paths are relative to the Socket scan
working directory, which defaults to the Basics workspace. `tests` matches only
the `tests` directory at that root; use `**/tests` to match it at any depth. The
option affects only the Socket Tier 1 CLI scan.

```bash
socket-basics --socket-tier1 --socket-additional-params="--exclude-paths=tests --exclude-paths=fixtures"
```

The same value can be set with `SOCKET_ADDITIONAL_PARAMS` or the GitHub Action's
`socket_additional_params` input:

```yaml
socket_tier_1_enabled: 'true'
socket_additional_params: '--exclude-paths=tests --exclude-paths=fixtures'
```

## Notification Options
Expand Down
2 changes: 1 addition & 1 deletion socket_basics/connectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ connectors:
default: false
- name: socket_additional_params
option: --socket-additional-params
description: "Additional CLI params for 'socket scan reach' (comma or space separated). Also reads SOCKET_ADDITIONAL_PARAMS"
description: "Additional CLI params for 'socket scan reach', using shell-style space separation. Commas in values are preserved; only an unquoted comma followed by a hyphen is a legacy separator. Repeat list-valued flags. Also reads SOCKET_ADDITIONAL_PARAMS."
env_variable: SOCKET_ADDITIONAL_PARAMS
type: str
default: ""
Expand Down
52 changes: 43 additions & 9 deletions socket_basics/core/connector/socket_tier1/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,43 @@
logger = logging.getLogger(__name__)


def _split_legacy_parameter_separators(raw: str) -> List[str]:
separated: List[str] = []
quote: Optional[str] = None
escaped: bool = False
index: int = 0

while index < len(raw):
char = raw[index]
if escaped:
separated.append(char)
escaped = False
elif char == "\\" and quote != "'":
separated.append(char)
escaped = True
elif quote:
separated.append(char)
if char == quote:
quote = None
elif char in ("'", '"'):
separated.append(char)
quote = char
elif char == ",":
next_index = index + 1
while next_index < len(raw) and raw[next_index].isspace():
next_index += 1
if next_index < len(raw) and raw[next_index] == "-":
separated.append(" ")
index = next_index - 1
else:
separated.append(char)
else:
separated.append(char)
index += 1

return shlex.split("".join(separated))


class SocketTier1Scanner(BaseConnector):
"""Runs the Socket CLI reachability analysis and returns the generated .socket.facts.json

Expand Down Expand Up @@ -89,15 +126,12 @@ def _parse_additional_params(self) -> List[str]:
)
if not raw:
return []
# Allow comma-separated or regular shell splitting
if ',' in raw:
parts = [p.strip() for p in raw.split(',') if p.strip()]
# further split any parts that contain spaces
out: List[str] = []
for p in parts:
out.extend(shlex.split(p))
return out
return shlex.split(raw)
try:
return _split_legacy_parameter_separators(raw)
except ValueError as error:
raise ConnectorExecutionError(
f"Invalid socket_additional_params: {error}"
) from error

def scan(self) -> Dict[str, Any]:
# Check if Socket Tier 1 reachability scan should be skipped (for Node.js Socket CLI integration).
Expand Down
60 changes: 60 additions & 0 deletions tests/test_socket_tier1_additional_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import pytest

from socket_basics.core.connector.base import ConnectorExecutionError
from socket_basics.core.connector.socket_tier1.scanner import SocketTier1Scanner


@pytest.mark.parametrize(
("raw", "expected"),
[
("", []),
(
"--exclude-paths=tests --exclude-paths=fixtures",
["--exclude-paths=tests", "--exclude-paths=fixtures"],
),
(
"--exclude-paths tests --exclude-paths fixtures",
["--exclude-paths", "tests", "--exclude-paths", "fixtures"],
),
(
"--exclude-paths='test data'",
["--exclude-paths=test data"],
),
(
'--exclude-paths="tests,fixtures"',
["--exclude-paths=tests,fixtures"],
),
("--exclude-paths=**/tests", ["--exclude-paths=**/tests"]),
("--view=full,--all", ["--view=full", "--all"]),
(
"--exclude-paths=tests,fixtures --view=full, --all "
'--exclude-paths "test data, -literal"',
[
"--exclude-paths=tests,fixtures",
"--view=full",
"--all",
"--exclude-paths",
"test data, -literal",
],
),
(
'--note="quoted, --option text"',
["--note=quoted, --option text"],
),
(r"--note=left\, --option", ["--note=left,", "--option"]),
],
)
def test_parse_additional_params_preserves_argument_boundaries(raw, expected):
scanner = SocketTier1Scanner({"socket_additional_params": raw})

assert scanner._parse_additional_params() == expected


def test_parse_additional_params_reports_malformed_shell_quotes():
scanner = SocketTier1Scanner({"socket_additional_params": '--exclude-paths "tests'})

with pytest.raises(
ConnectorExecutionError,
match="Invalid socket_additional_params: No closing quotation",
):
scanner._parse_additional_params()
Loading