st2 icon indicating copy to clipboard operation
st2 copied to clipboard

python_runner.py should check the utf8 length to determine when to use stdin for parameters.

Open guzzijones opened this issue 9 months ago • 1 comments

SUMMARY

python_runner.py should check the utf8 length to determine when to use stdin for parameters.

Provide a quick summary of your bug report.

        # If parameter size is larger than the maximum allowed by Linux kernel
        # we need to swap to stdin to communicate parameters. This avoids a
        # failure to fork the wrapper process when using large parameters.
        stdin = None
        stdin_params = None
        lenencoded = len(serialized_parameters.encode("utf8"))
        LOG.debug(f"Parameters len encoded: {lenencoded}")
        if len(serialized_parameters) >= MAX_PARAM_LENGTH:
            stdin = subprocess.PIPE
            LOG.debug("Parameters are too big...changing to stdin")
            stdin_params = '{"parameters": %s}\n' % (serialized_parameters)
            args.append("--stdin-parameters")
        else:
            LOG.debug("Parameters are just right...adding them to arguments")
            args.append("--parameters=%s" % (serialized_parameters))

check against MAX_PARAM_LENGTH should use lenencoded . high bit character strings will end up longer than the length of the unicode string.

STACKSTORM VERSION

3.9

OS, environment, install method

all

Steps to reproduce the problem

use a string with high bit characters and a unicode string length > (131072 -15)

Expected Results

action runs without error

Actual Results

[Errno 7] Argument list too long: '/opt/stackstorm/virtualenvs/rt/bin/python'

guzzijones avatar Apr 29 '25 16:04 guzzijones

The byte length should be checked instead of the number of characters

        MAX_PARAM_LENGTH = 131072
        length = 100000
        serialized_parameters = ''.join(chr(random.randint(0x4e00, 0x9fa5)) for _ in range(length))

        # bad
        if len(serialized_parameters) >= MAX_PARAM_LENGTH:
            print("Parameters are too big...changing to stdin")

        # ok
        if len(serialized_parameters.encode("utf-8")) >= MAX_PARAM_LENGTH:
            print("Parameters are too big...changing to stdin")
xargs --show-limits

Your environment variables take up 2919 bytes

POSIX upper limit on argument length (this system): 2092185

POSIX smallest allowable upper limit on argument length (all systems): 4096

Maximum length of command we could actually use: 2089266

Size of command buffer we are actually using: 131072

Execution of xargs will continue now, and it will try to read its input and run commands; if this is not what you wanted to happen, please type the end-of-file keystroke.

Warning: echo will be run at least once.  If you do not want that to happen, then press the interrupt keystroke.

banjintaohua avatar Jun 09 '25 01:06 banjintaohua