[elbe-devel] [PATCH v2] soapclient: Fix base64 encoding

Torben Hohn torben.hohn at linutronix.de
Tue Jul 21 12:16:00 CEST 2020


On Mon, Jul 20, 2020 at 08:33:45PM -0400, Olivier Dion wrote:
> In Py2, binascii.b2a_base64 returns a 'str' object, but in Py3
> a 'bytes' object is returned.
> 
> The soap service apparently get confused when the data is a 'bytes'
> object and will somehow add an extra 4 bytes at the end of the data.
> This is the reason why cdrom upload did not work, because the upload
> got corrupted.
> 
> Thus, the static method 'upload_file' defined for ClientAction can be
> used by sub-classes.  This method ensures that the data is of type
> 'str'.
> 
> Signed-off-by: Olivier Dion <dion at linutronix.de>

Reviewed-by: Torben Hohn <torben.hohn at linutronix.de>

> ---
>  elbepack/soapclient.py | 64 +++++++++++++++++++++++-------------------
>  1 file changed, 35 insertions(+), 29 deletions(-)
> 
> diff --git a/elbepack/soapclient.py b/elbepack/soapclient.py
> index a465b615..c8acc217 100644
> --- a/elbepack/soapclient.py
> +++ b/elbepack/soapclient.py
> @@ -146,6 +146,26 @@ class ClientAction(object):
>      def __init__(self, node):
>          self.node = node
>  
> +    @staticmethod
> +    def upload_file(append, build_dir, filename):
> +
> +        size = 1024 * 1024
> +
> +        with open(filename, "rb") as f:
> +
> +            while True:
> +
> +                bin_data = f.read(size)
> +                data = binascii.b2a_base64(bin_data)
> +
> +                if not isinstance(data, str):
> +                    data = data.decode("ascii")
> +
> +                append(build_dir, data)
> +
> +                if len(bin_data) != size:
> +                    break
> +
>      def execute(self, _client, _opt, _args):
>          raise NotImplementedError('execute() not implemented')
>  
> @@ -331,7 +351,12 @@ class SetXmlAction(ClientAction):
>          part = 0
>          with open(filename, "rb") as fp:
>              while True:
> -                xml_base64 = binascii.b2a_base64(fp.read(size)).decode('ascii')
> +
> +                xml_base64 = binascii.b2a_base64(fp.read(size))
> +
> +                if not isinstance(xml_base64, str):
> +                    xml_base64 = xml_base64.decode('ascii')
> +
>                  # finish upload
>                  if len(xml_base64) == 1:
>                      part = client.service.upload_file(builddir,
> @@ -634,7 +659,6 @@ class SetCdromAction(ClientAction):
>          ClientAction.__init__(self, node)
>  
>      def execute(self, client, _opt, args):
> -        size = 1024 * 1024
>  
>          if len(args) != 2:
>              print(
> @@ -645,17 +669,10 @@ class SetCdromAction(ClientAction):
>          builddir = args[0]
>          filename = args[1]
>  
> -        fp = open(filename, "rb")
>          client.service.start_cdrom(builddir)
> -        while True:
> -            bindata = fp.read(size)
> -            client.service.append_cdrom(builddir, binascii.b2a_base64(bindata))
> -            if len(bindata) != size:
> -                break
> -
> +        self.upload_file(client.service.append_cdrom, builddir, filename)
>          client.service.finish_cdrom(builddir)
>  
> -
>  ClientAction.register(SetCdromAction)
>  
>  
> @@ -667,7 +684,6 @@ class SetOrigAction(ClientAction):
>          ClientAction.__init__(self, node)
>  
>      def execute(self, client, _opt, args):
> -        size = 1024 * 1024
>  
>          if len(args) != 2:
>              print(
> @@ -678,18 +694,10 @@ class SetOrigAction(ClientAction):
>          builddir = args[0]
>          filename = args[1]
>  
> -        fp = open(filename, "r")
>          client.service.start_upload_orig(builddir, os.path.basename(filename))
> -        while True:
> -            bindata = fp.read(size)
> -            client.service.append_upload_orig(
> -                builddir, binascii.b2a_base64(bindata))
> -            if len(bindata) != size:
> -                break
> -
> +        self.upload_file(client.service.append_upload_orig, builddir, filename)
>          client.service.finish_upload_orig(builddir)
>  
> -
>  ClientAction.register(SetOrigAction)
>  
>  
> @@ -723,7 +731,6 @@ class SetPdebuilderAction(ClientAction):
>          ClientAction.__init__(self, node)
>  
>      def execute(self, client, opt, args):
> -        size = 1024 * 1024
>  
>          if len(args) != 2 and len(args) != 3:
>              print("usage: elbe control set_pdebuild "
> @@ -733,15 +740,8 @@ class SetPdebuilderAction(ClientAction):
>          builddir = args[0]
>          filename = args[1]
>  
> -        fp = open(filename, "r")
>          client.service.start_pdebuild(builddir)
> -        while True:
> -            bindata = fp.read(size)
> -            client.service.append_pdebuild(
> -                builddir, binascii.b2a_base64(bindata))
> -            if len(bindata) != size:
> -                break
> -
> +        self.upload_file(client.service.append_pdebuild, builddir, filename)
>          client.service.finish_pdebuild(builddir, opt.cpuset,
>                                         opt.profile, opt.cross)
>  
> @@ -901,6 +901,7 @@ class UploadPackageAction(RepoAction):
>      def __init__(self, node):
>          RepoAction.__init__(self, node)
>  
> +    # pylint: disable=arguments-differ
>      @staticmethod
>      def upload_file(client, f, builddir):
>          # Uploads file f into builddir in intivm
> @@ -908,7 +909,12 @@ class UploadPackageAction(RepoAction):
>          part = 0
>          with open(f, "rb") as fp:
>              while True:
> +
>                  xml_base64 = binascii.b2a_base64(fp.read(size))
> +
> +                if not isinstance(xml_base64, str):
> +                    xml_base64 = xml_base64.decode("ascii")
> +
>                  # finish upload
>                  if len(xml_base64) == 1:
>                      part = client.service.upload_file(builddir,
> -- 
> 2.27.0
> 
> _______________________________________________
> elbe-devel mailing list
> elbe-devel at linutronix.de
> https://lists.linutronix.de/mailman/listinfo/elbe-devel

-- 
Torben Hohn
Linutronix GmbH | Bahnhofstrasse 3 | D-88690 Uhldingen-Mühlhofen
Phone: +49 7556 25 999 18; Fax.: +49 7556 25 999 99

Hinweise zum Datenschutz finden Sie hier (Informations on data privacy 
can be found here): https://linutronix.de/kontakt/Datenschutz.php

Linutronix GmbH | Firmensitz (Registered Office): Uhldingen-Mühlhofen | 
Registergericht (Registration Court): Amtsgericht Freiburg i.Br., HRB700 
806 | Geschäftsführer (Managing Directors): Heinz Egger, Thomas Gleixner


More information about the elbe-devel mailing list