← Back to team overview

curtin-dev team mailing list archive

Re: [Merge] ~raharper/curtin:fix/udevadm-info-shlex-quote into curtin:master

 

Thanks

Diff comments:

> diff --git a/curtin/udev.py b/curtin/udev.py
> index e2e3dd0..0908bc9 100644
> --- a/curtin/udev.py
> +++ b/curtin/udev.py
> @@ -4,7 +4,14 @@ import shlex
>  import os
>  
>  from curtin import util
> -from curtin.log import logged_call
> +from curtin.log import logged_call, LOG
> +
> +try:
> +    shlex_quote = shlex.quote
> +except AttributeError:
> +    # python2.7 shlex does not have quote, give it a try
> +    def shlex_quote(value):

Yes, that seems *much* better.  Thanks for tracking it down.

> +        return ("'" + value.replace("'", "\'\"\'\"\'") + "'")
>  
>  
>  def compose_udev_equality(key, value):
> @@ -90,7 +97,22 @@ def udevadm_info(path=None):
>              value = None
>          if value:
>              # preserve spaces in values to match udev database
> -            parsed = shlex.split(value)
> +            try:
> +                parsed = shlex.split(value)
> +            except ValueError:
> +                try:
> +                    # strip the leading/ending single tick from udev output
> +                    quoted = shlex_quote(value[1:-1])
> +                    LOG.debug('udevadm_info: quoting shell-escape chars '
> +                              'in %s=%s -> %s', key, value, quoted)
> +                    parsed = shlex.split(quoted)
> +                except ValueError:
> +                    # strip the leading/ending single tick from udev output

I'll rework.

> +                    escaped_value = (
> +                        value[1:-1].replace("'", "_").replace('"', "_"))
> +                    LOG.debug('udevadm_info: replacing shell-escape chars '
> +                              'in %s=%s -> %s', key, value, escaped_value)
> +                    parsed = shlex.split(escaped_value)
>              if ' ' not in value:
>                  info[key] = parsed[0]
>              else:
> diff --git a/tests/unittests/test_udev.py b/tests/unittests/test_udev.py
> index 33d5f44..0c6c5b9 100644
> --- a/tests/unittests/test_udev.py
> +++ b/tests/unittests/test_udev.py
> @@ -54,6 +55,19 @@ class TestUdevInfo(CiTestCase):
>              capture=True)
>          self.assertEqual(sorted(INFO_DICT), sorted(info))
>  
> +    @mock.patch('curtin.util.subp')
> +    def test_udevadm_info_escape_quotes(self, m_subp):
> +        """verify we escape quotes when we fail to split. """
> +        mypath = '/dev/sdz'
> +        datafile = 'tests/data/udevadm_info_sandisk_cruzer.txt'
> +        m_subp.return_value = (util.load_file(datafile), "")
> +        info = udev.udevadm_info(mypath)
> +        m_subp.assert_called_with(
> +            ['udevadm', 'info', '--query=property', '--export', mypath],
> +            capture=True)
> +        self.assertEqual('SanDisk'"'"'', info['SCSI_VENDOR'])

What's wrong with matching the exact output from shlex_quote() ?

% python3
Python 3.8.2 (default, Mar 13 2020, 10:14:16) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import shlex
>>> shlex.quote("SanDisk'")
'\'SanDisk\'"\'"\'\''
>>> print(shlex.quote("SanDisk'"))
'SanDisk'"'"''
>>>

> +        self.assertEqual('SanDisk'"'"'', info['SCSI_VENDOR_ENC'])
> +
>      def test_udevadm_info_no_path(self):
>          """ udevadm_info raises ValueError for invalid path value"""
>          mypath = None


-- 
https://code.launchpad.net/~raharper/curtin/+git/curtin/+merge/382993
Your team curtin developers is subscribed to branch curtin:master.


Follow ups

References