Skip to content

Commit

Permalink
pkg_deb: Create deb pkgs with unicode descriptions
Browse files Browse the repository at this point in the history
pkg_deb would fail with an error when attempting to create debian
packages with descriptions containing unicode characters or with
utf-8 encoded description_files. Python's bytes objects can only
contain ascii literal characters and so need decoding when they
are sent to strings and non-ascii strings need encoding when sent
to bytes objects.

Resolves: #7370

Testing Done:
- bazel test tools/build_defs/pkg:build_test

Closes #7484.

PiperOrigin-RevId: 240218536
  • Loading branch information
imcginnis authored and copybara-github committed Mar 25, 2019
1 parent 7363e84 commit 70e3c33
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 30 deletions.
5 changes: 3 additions & 2 deletions tools/build_defs/pkg/BUILD
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
licenses(["notice"]) # Apache 2.0

filegroup(
Expand Down Expand Up @@ -213,9 +214,9 @@ pkg_deb(
"dep1",
"dep2",
],
description = "toto",
description = "toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é",
distribution = "trusty",
maintainer = "someone@somewhere.com",
maintainer = "soméone@somewhere.com",
make_deb = ":make_deb",
package = "titi",
urgency = "low",
Expand Down
4 changes: 3 additions & 1 deletion tools/build_defs/pkg/build_test.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
# -*- coding: utf-8 -*-

# Copyright 2015 The Bazel Authors. All rights reserved.
#
Expand Down Expand Up @@ -181,8 +182,9 @@ function test_deb() {
check_eq "-rwxr-xr-x" "$(get_deb_permission test-deb.deb ./usr/titi)"
check_eq "-rw-r--r--" "$(get_deb_permission test-deb.deb ./etc/nsswitch.conf)"
get_deb_description test-deb.deb >$TEST_log
expect_log "Description: toto"
expect_log "Description: toto ®, Й, ק ,م, ๗, あ, 叶, 葉, 말, ü and é"
expect_log "Package: titi"
expect_log "somé[email protected]"
expect_log "Depends: dep1, dep2"

get_changes titi_test_all.changes >$TEST_log
Expand Down
67 changes: 40 additions & 27 deletions tools/build_defs/pkg/make_deb.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@


def MakeGflags():
"""Creates a flag for each of the control file fields."""
for field in DEBIAN_FIELDS:
fieldname = field[0].replace('-', '_').lower()
msg = 'The value for the %s content header entry.' % field[0]
if len(field) > 3:
if type(field[3]) is list:
if isinstance(field[3], list):
gflags.DEFINE_multistring(fieldname, field[3], msg)
else:
gflags.DEFINE_string(fieldname, field[3], msg)
Expand Down Expand Up @@ -133,16 +134,18 @@ def AddArFileEntry(fileobj, filename,
def MakeDebianControlField(name, value, wrap=False):
"""Add a field to a debian control file."""
result = name + ': '
if type(value) is list:
value = ', '.join(value)
if isinstance(value, str):
value = value.decode('utf-8')
if isinstance(value, list):
value = u', '.join(value)
if wrap:
result += ' '.join(value.split('\n'))
result += u' '.join(value.split('\n'))

This comment has been minimized.

Copy link
@qzmfranklin

qzmfranklin May 27, 2019

Such paradigm of using u'' strings is python2-like and is likely to break under python3.

Suggest adding py_test for make_deb.py to run under both python2 and python3 to avoid such regressions as #8465

result = textwrap.fill(result,
break_on_hyphens=False,
break_long_words=False)
else:
result += value
return result.replace('\n', '\n ') + '\n'
return result.replace(u'\n', u'\n ') + u'\n'


def CreateDebControl(extrafiles=None, **kwargs):
Expand All @@ -159,7 +162,8 @@ def CreateDebControl(extrafiles=None, **kwargs):
with gzip.GzipFile('control.tar.gz', mode='w', fileobj=tar, mtime=0) as gz:
with tarfile.open('control.tar.gz', mode='w', fileobj=gz) as f:
tarinfo = tarfile.TarInfo('control')
tarinfo.size = len(controlfile)
# Don't discard unicode characters when computing the size
tarinfo.size = len(controlfile.encode('utf-8'))
f.addfile(tarinfo, fileobj=BytesIO(controlfile.encode('utf-8')))
if extrafiles:
for name, (data, mode) in extrafiles.items():
Expand Down Expand Up @@ -261,34 +265,43 @@ def CreateChanges(output,
debsize = str(os.path.getsize(deb_file))
deb_basename = os.path.basename(deb_file)

changesdata = ''.join(
MakeDebianControlField(*x)
for x in [('Format', '1.8'), ('Date', time.ctime(timestamp)), (
'Source', package
), ('Binary', package
), ('Architecture', architecture), ('Version', version), (
'Distribution', distribution
), ('Urgency', urgency), ('Maintainer', maintainer), (
'Changed-By', maintainer
), ('Description', '\n%s - %s' % (package, short_description)
), ('Changes', ('\n%s (%s) %s; urgency=%s'
'\nChanges are tracked in revision control.'
) % (package, version, distribution, urgency)
), ('Files', '\n' + ' '.join(
[checksums['md5'], debsize, section, priority, deb_basename])
), ('Checksums-Sha1', '\n' + ' '.join(
[checksums['sha1'], debsize, deb_basename])
), ('Checksums-Sha256', '\n' + ' '.join(
[checksums['sha256'], debsize, deb_basename]))])
changesdata = ''.join([
MakeDebianControlField('Format', '1.8'),
MakeDebianControlField('Date', time.ctime(timestamp)),
MakeDebianControlField('Source', package),
MakeDebianControlField('Binary', package),
MakeDebianControlField('Architecture', architecture),
MakeDebianControlField('Version', version),
MakeDebianControlField('Distribution', distribution),
MakeDebianControlField('Urgency', urgency),
MakeDebianControlField('Maintainer', maintainer),
MakeDebianControlField('Changed-By', maintainer),
MakeDebianControlField('Description',
'\n%s - %s' % (package, short_description)),
MakeDebianControlField('Changes',
('\n%s (%s) %s; urgency=%s'
'\nChanges are tracked in revision control.') %
(package, version, distribution, urgency)),
MakeDebianControlField(
'Files', '\n' + ' '.join(
[checksums['md5'], debsize, section, priority, deb_basename])),
MakeDebianControlField(
'Checksums-Sha1',
'\n' + ' '.join([checksums['sha1'], debsize, deb_basename])),
MakeDebianControlField(
'Checksums-Sha256',
'\n' + ' '.join([checksums['sha256'], debsize, deb_basename]))
])
with open(output, 'w') as changes_fh:
changes_fh.write(changesdata)
changes_fh.write(changesdata.encode('utf-8'))


def GetFlagValue(flagvalue, strip=True):
if flagvalue:
flagvalue = flagvalue.decode('utf-8')
if flagvalue[0] == '@':
with open(flagvalue[1:], 'r') as f:
flagvalue = f.read()
flagvalue = f.read().decode('utf-8')

This comment has been minimized.

Copy link
@qzmfranklin

qzmfranklin May 27, 2019

This line is breaking this script under python3

This comment has been minimized.

Copy link
@qzmfranklin
if strip:
return flagvalue.strip()
return flagvalue
Expand Down

0 comments on commit 70e3c33

Please sign in to comment.