From 32478701a59f60a30b0f5454d8c335845a13273d Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Tue, 21 Feb 2023 17:05:14 +0530 Subject: [PATCH 1/7] Fix code block language: bash -> console --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c54eb90..9982743 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ for filename in test_files: Output: -```bash +```console $ ./run_all_tests.py Running ./tests/python_version_test.py....................Test failed. Running ./tests/platform_test.py..........................Test passed! From 6f2abc1cc1f0af40b1119ad974678bba75682d7d Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Tue, 21 Feb 2023 22:50:20 +0530 Subject: [PATCH 2/7] Add injection tests for shell arguments --- tests/test_files/injection.py | 9 +++++++++ tests/zxpy_test.py | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/test_files/injection.py b/tests/test_files/injection.py index 83fd930..2d4ef10 100644 --- a/tests/test_files/injection.py +++ b/tests/test_files/injection.py @@ -4,3 +4,12 @@ command = "uname -p" _, _, rc = ~f"{command}" # This doesn't work print(rc) + +print(~"echo $1", end='') +print(~'echo "$1"', end='') +print(~"echo '$1'", end='') + +argument = "$1" +quoted_argument = '"$1"' +print(~f"echo {argument}", end='') +print(~f"echo {quoted_argument}", end='') diff --git a/tests/zxpy_test.py b/tests/zxpy_test.py index b371d4f..6c9a79d 100644 --- a/tests/zxpy_test.py +++ b/tests/zxpy_test.py @@ -170,5 +170,9 @@ def test_shell_injection(): assert output == ( "True\n" # uname -p worked as a string "127\n" # uname -p inside f-string got quoted + "abc\n" # $1 works + "abc\n" # "$1" works + "$1\n" # '$1 is printed as-is + "$1\n" # $1 in an f-string gets quoted to '$1' + '"$1"\n' # "$1" in an f-string gets quoted to '"$1"' ) - # TODO: $1 injection test From b50db55eba87327b8fa56211c9d2a12194ef7fa0 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 16 Aug 2023 00:15:43 +0530 Subject: [PATCH 3/7] Update downloads badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9982743..c598ccc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # zxpy -[![Downloads](https://pepy.tech/badge/zxpy)](https://pepy.tech/project/zxpy) +[![Downloads](https://static.pepy.tech/badge/zxpy)](https://pepy.tech/project/zxpy) [![Code style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![CI Status](https://github.com/tusharsadhwani/zxpy/actions/workflows/tox.yml/badge.svg)](https://github.com/tusharsadhwani/zxpy/actions/workflows/tox.yml) From 2baf656d2bdd453abca5f171f1d64fc11e91a189 Mon Sep 17 00:00:00 2001 From: figsoda Date: Sat, 9 Sep 2023 01:11:06 -0400 Subject: [PATCH 4/7] Allow unknown processor in injection test (#53) --- tests/test_files/injection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_files/injection.py b/tests/test_files/injection.py index 2d4ef10..f9b0788 100644 --- a/tests/test_files/injection.py +++ b/tests/test_files/injection.py @@ -1,5 +1,5 @@ x = ~"uname -p" -print(x in ("arm\n", "x86_64\n")) +print(x in ("arm\n", "unknown\n", "x86_64\n")) command = "uname -p" _, _, rc = ~f"{command}" # This doesn't work From d6de402e939cf98f7ef147db0371e3bf82cc1d4c Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Sat, 7 Sep 2024 03:32:42 +0530 Subject: [PATCH 5/7] Add support for Python 3.13, drop 3.7 --- setup.cfg | 6 ++++-- zx.py | 33 ++++++++++++++------------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/setup.cfg b/setup.cfg index b47bc48..e47cf59 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = zxpy -version = 1.6.3 +version = 1.6.4 description = Shell scripts made simple long_description = file: README.md long_description_content_type = text/markdown @@ -14,10 +14,12 @@ classifiers = Operating System :: OS Independent Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Programming Language :: Python :: Implementation :: CPython Typing :: Typed diff --git a/zx.py b/zx.py index cabb4ef..dd1559c 100644 --- a/zx.py +++ b/zx.py @@ -21,6 +21,7 @@ ...to the top of your file, and executing it directly like a shell script. Note that this requires you to have zxpy installed globally. """ + from __future__ import annotations import argparse @@ -29,8 +30,6 @@ import codecs import contextlib import inspect -import pipes -import re import shlex import subprocess import sys @@ -59,17 +58,17 @@ def cli() -> None: """ parser = argparse.ArgumentParser() parser.add_argument( - '-i', - '--interactive', - action='store_true', - help='Run in interactive mode', + "-i", + "--interactive", + action="store_true", + help="Run in interactive mode", ) - parser.add_argument('filename', help='Name of file to run', nargs='?') + parser.add_argument("filename", help="Name of file to run", nargs="?") # Everything passed after a `--` is arguments to be used by the script itself. - script_args = ['/bin/sh'] + script_args = ["/bin/sh"] try: - separator_index = sys.argv.index('--') + separator_index = sys.argv.index("--") script_args.extend(sys.argv[separator_index + 1 :]) # Remove everything after `--` so that argparse passes sys.argv = sys.argv[:separator_index] @@ -146,7 +145,7 @@ def create_shell_process(command: str) -> Generator[IO[bytes], None, None]: """Creates a shell process, yielding its stdout to read data from.""" # shell argument support, i.e. $0, $1 etc. - dollar_indices = [index for index, char in enumerate(command) if char == '$'] + dollar_indices = [index for index, char in enumerate(command) if char == "$"] for dollar_index in reversed(dollar_indices): if ( dollar_index >= 0 @@ -194,7 +193,7 @@ def run_shell_print(command: str) -> None: """Version of `run_shell` that prints out the response instead of returning a string.""" with create_shell_process(command) as stdout: decoder = UTF8Decoder() - with open(stdout.fileno(), 'rb', closefd=False) as buff: + with open(stdout.fileno(), "rb", closefd=False) as buff: for text in iter(buff.read1, b""): print(decoder.decode(text), end="") @@ -261,12 +260,8 @@ def quote_fstring_args(fstring: ast.JoinedStr) -> None: if ( isinstance(node.format_spec, ast.JoinedStr) and len(node.format_spec.values) == 1 - and ( - isinstance(node.format_spec.values[0], ast.Str) - and node.format_spec.values[0].s == "raw" - or isinstance(node.format_spec.values[0], ast.Constant) - and node.format_spec.values[0].value == "raw" - ) + and isinstance(node.format_spec.values[0], ast.Constant) + and node.format_spec.values[0].value == "raw" ): node.format_spec = None continue @@ -290,7 +285,7 @@ def modify_expr( if ( isinstance(expr, ast.UnaryOp) and isinstance(expr.op, ast.Invert) - and isinstance(expr.operand, (ast.Str, ast.JoinedStr)) + and isinstance(expr.operand, (ast.Constant, ast.JoinedStr)) ): if isinstance(expr.operand, ast.JoinedStr): quote_fstring_args(expr.operand) @@ -362,7 +357,7 @@ def runsource( # First, check if it could be incomplete input, return True if it is. # This will allow it to keep taking input with contextlib.suppress(SyntaxError, OverflowError): - if code.compile_command(source) == None: + if code.compile_command(source) is None: return True try: From a8b3dfc806e2914f34117f65d0d39d64bc40ef71 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Sat, 7 Sep 2024 03:35:03 +0530 Subject: [PATCH 6/7] Run CI on 3.8-3.13 --- .github/workflows/tox.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 91d7235..5150886 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] name: Python ${{ matrix.python-version }} tests steps: - uses: actions/checkout@v2 From 172043df0ccbbcb64038ccf44e4c44caa08c8c0e Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Sat, 7 Sep 2024 03:35:54 +0530 Subject: [PATCH 7/7] 3.13 machines don't exist yet --- .github/workflows/tox.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 5150886..0531d4b 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] # , "3.13"] name: Python ${{ matrix.python-version }} tests steps: - uses: actions/checkout@v2