mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #47041 from terminalmage/issue46909
Force null bytes to be str types
This commit is contained in:
commit
d6c59696be
9 changed files with 72 additions and 19 deletions
|
@ -5230,12 +5230,12 @@ def manage_file(name,
|
|||
if salt.utils.platform.is_windows():
|
||||
contents = os.linesep.join(
|
||||
_splitlines_preserving_trailing_newline(contents))
|
||||
with salt.utils.files.fopen(tmp, 'w') as tmp_:
|
||||
with salt.utils.files.fopen(tmp, 'wb') as tmp_:
|
||||
if encoding:
|
||||
log.debug('File will be encoded with {0}'.format(encoding))
|
||||
log.debug('File will be encoded with %s', encoding)
|
||||
tmp_.write(contents.encode(encoding=encoding, errors=encoding_errors))
|
||||
else:
|
||||
tmp_.write(salt.utils.stringutils.to_str(contents))
|
||||
tmp_.write(salt.utils.stringutils.to_bytes(contents))
|
||||
|
||||
try:
|
||||
differences = get_diff(
|
||||
|
@ -5438,12 +5438,12 @@ def manage_file(name,
|
|||
if salt.utils.platform.is_windows():
|
||||
contents = os.linesep.join(
|
||||
_splitlines_preserving_trailing_newline(contents))
|
||||
with salt.utils.files.fopen(tmp, 'w') as tmp_:
|
||||
with salt.utils.files.fopen(tmp, 'wb') as tmp_:
|
||||
if encoding:
|
||||
log.debug('File will be encoded with {0}'.format(encoding))
|
||||
log.debug('File will be encoded with %s', encoding)
|
||||
tmp_.write(contents.encode(encoding=encoding, errors=encoding_errors))
|
||||
else:
|
||||
tmp_.write(salt.utils.stringutils.to_str(contents))
|
||||
tmp_.write(salt.utils.stringutils.to_bytes(contents))
|
||||
|
||||
# Copy into place
|
||||
salt.utils.files.copyfile(tmp,
|
||||
|
|
|
@ -4574,7 +4574,7 @@ def status(cwd,
|
|||
password=password,
|
||||
ignore_retcode=ignore_retcode,
|
||||
output_encoding=output_encoding)['stdout']
|
||||
for line in output.split('\0'):
|
||||
for line in output.split(str('\0')):
|
||||
try:
|
||||
state, filename = line.split(None, 1)
|
||||
except ValueError:
|
||||
|
|
|
@ -2269,9 +2269,9 @@ def managed(name,
|
|||
.format(contents_id)
|
||||
)
|
||||
|
||||
contents_are_binary = \
|
||||
isinstance(use_contents, six.string_types) and '\0' in use_contents
|
||||
if contents_are_binary:
|
||||
if isinstance(use_contents, bytes) and b'\0' in use_contents:
|
||||
contents = use_contents
|
||||
elif isinstance(use_contents, six.string_types) and str('\0') in use_contents:
|
||||
contents = use_contents
|
||||
else:
|
||||
validated_contents = _validate_str_list(use_contents)
|
||||
|
|
|
@ -637,7 +637,7 @@ class TCPReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt.tra
|
|||
|
||||
try:
|
||||
id_ = payload['load'].get('id', '')
|
||||
if '\0' in id_:
|
||||
if str('\0') in id_:
|
||||
log.error('Payload contains an id with a null byte: %s', payload)
|
||||
stream.send(self.serial.dumps('bad load: id contains a null byte'))
|
||||
raise tornado.gen.Return()
|
||||
|
|
|
@ -662,7 +662,7 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin,
|
|||
|
||||
try:
|
||||
id_ = payload['load'].get('id', '')
|
||||
if '\0' in id_:
|
||||
if str('\0') in id_:
|
||||
log.error('Payload contains an id with a null byte: %s', payload)
|
||||
stream.send(self.serial.dumps('bad load: id contains a null byte'))
|
||||
raise tornado.gen.Return()
|
||||
|
|
|
@ -190,19 +190,27 @@ def is_binary(data):
|
|||
'''
|
||||
Detects if the passed string of data is binary or text
|
||||
'''
|
||||
if not data or not isinstance(data, six.string_types):
|
||||
if not data or not isinstance(data, (six.string_types, six.binary_type)):
|
||||
return False
|
||||
if '\0' in data:
|
||||
|
||||
if isinstance(data, six.binary_type):
|
||||
if b'\0' in data:
|
||||
return True
|
||||
elif str('\0') in data:
|
||||
return True
|
||||
|
||||
text_characters = ''.join([chr(x) for x in range(32, 127)] + list('\n\r\t\b'))
|
||||
# Get the non-text characters (map each character to itself then use the
|
||||
# 'remove' option to get rid of the text characters.)
|
||||
if six.PY3:
|
||||
trans = ''.maketrans('', '', text_characters)
|
||||
nontext = data.translate(trans)
|
||||
if isinstance(data, six.binary_type):
|
||||
import salt.utils.data
|
||||
nontext = data.translate(None, salt.utils.data.encode(text_characters))
|
||||
else:
|
||||
trans = ''.maketrans('', '', text_characters)
|
||||
nontext = data.translate(trans)
|
||||
else:
|
||||
if isinstance(data, unicode): # pylint: disable=incompatible-py3-code
|
||||
if isinstance(data, six.text_type):
|
||||
trans_args = ({ord(x): None for x in text_characters},)
|
||||
else:
|
||||
trans_args = (None, str(text_characters)) # future lint: blacklisted-function
|
||||
|
|
|
@ -497,7 +497,7 @@ def valid_id(opts, id_):
|
|||
Returns if the passed id is valid
|
||||
'''
|
||||
try:
|
||||
if any(x in id_ for x in ('/', '\\', '\0')):
|
||||
if any(x in id_ for x in ('/', '\\', str('\0'))):
|
||||
return False
|
||||
return bool(clean_path(opts['pki_dir'], id_))
|
||||
except (AttributeError, KeyError, TypeError):
|
||||
|
|
|
@ -57,6 +57,8 @@ from salt.ext.six.moves import range # pylint: disable=import-error,redefined-b
|
|||
|
||||
IS_WINDOWS = salt.utils.platform.is_windows()
|
||||
|
||||
BINARY_FILE = b'GIF89a\x01\x00\x01\x00\x80\x00\x00\x05\x04\x04\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;'
|
||||
|
||||
STATE_DIR = os.path.join(FILES, 'file', 'base')
|
||||
if IS_WINDOWS:
|
||||
FILEPILLAR = 'C:\\Windows\\Temp\\filepillar-python'
|
||||
|
@ -2190,7 +2192,8 @@ class FileTest(ModuleCase, SaltReturnAssertsMixin):
|
|||
'some-utf8-file-create:',
|
||||
' file.managed:',
|
||||
" - name: '{0}'".format(test_file),
|
||||
" - contents: {0}".format(korean_1),
|
||||
' - contents: |',
|
||||
' {0}'.format(korean_1),
|
||||
' - makedirs: True',
|
||||
' - replace: True',
|
||||
' - show_diff: True',
|
||||
|
@ -2503,6 +2506,23 @@ class FileTest(ModuleCase, SaltReturnAssertsMixin):
|
|||
ret = self.run_function('state.sls', mods=state_file)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
||||
def test_binary_contents(self):
|
||||
'''
|
||||
This tests to ensure that binary contents do not cause a traceback.
|
||||
'''
|
||||
name = os.path.join(TMP, '1px.gif')
|
||||
try:
|
||||
ret = self.run_state(
|
||||
'file.managed',
|
||||
name=name,
|
||||
contents=BINARY_FILE)
|
||||
self.assertSaltTrueReturn(ret)
|
||||
finally:
|
||||
try:
|
||||
os.remove(name)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
class BlockreplaceTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
marker_start = '# start'
|
||||
|
|
|
@ -37,19 +37,44 @@ class StringutilsTestCase(TestCase):
|
|||
|
||||
def test_is_binary(self):
|
||||
self.assertFalse(salt.utils.stringutils.is_binary(LOREM_IPSUM))
|
||||
# Also test bytestring
|
||||
self.assertFalse(
|
||||
salt.utils.stringutils.is_binary(
|
||||
salt.utils.stringutils.is_binary(LOREM_IPSUM)
|
||||
)
|
||||
)
|
||||
|
||||
zero_str = '{0}{1}'.format(LOREM_IPSUM, '\0')
|
||||
self.assertTrue(salt.utils.stringutils.is_binary(zero_str))
|
||||
# Also test bytestring
|
||||
self.assertTrue(
|
||||
salt.utils.stringutils.is_binary(
|
||||
salt.utils.stringutils.to_bytes(zero_str)
|
||||
)
|
||||
)
|
||||
|
||||
# To to ensure safe exit if str passed doesn't evaluate to True
|
||||
self.assertFalse(salt.utils.stringutils.is_binary(''))
|
||||
self.assertFalse(salt.utils.stringutils.is_binary(b''))
|
||||
|
||||
nontext = 3 * (''.join([chr(x) for x in range(1, 32) if x not in (8, 9, 10, 12, 13)]))
|
||||
almost_bin_str = '{0}{1}'.format(LOREM_IPSUM[:100], nontext[:42])
|
||||
self.assertFalse(salt.utils.stringutils.is_binary(almost_bin_str))
|
||||
# Also test bytestring
|
||||
self.assertFalse(
|
||||
salt.utils.stringutils.is_binary(
|
||||
salt.utils.stringutils.to_bytes(almost_bin_str)
|
||||
)
|
||||
)
|
||||
|
||||
bin_str = almost_bin_str + '\x01'
|
||||
self.assertTrue(salt.utils.stringutils.is_binary(bin_str))
|
||||
# Also test bytestring
|
||||
self.assertTrue(
|
||||
salt.utils.stringutils.is_binary(
|
||||
salt.utils.stringutils.to_bytes(bin_str)
|
||||
)
|
||||
)
|
||||
|
||||
def test_to_str(self):
|
||||
for x in (123, (1, 2, 3), [1, 2, 3], {1: 23}, None):
|
||||
|
|
Loading…
Add table
Reference in a new issue