1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-08-22 22:48:51 +02:00

Merge branch 'master' into maint_enforce_branch

This commit is contained in:
Marco Strigl
2019-07-25 13:46:18 +02:00
committed by GitHub
6 changed files with 101 additions and 74 deletions

8
NEWS
View File

@@ -1,6 +1,12 @@
0.166.0 0.166.0
- allow optional fork when creating a maintenance request - allow optional fork when creating a maintenance request
-
0.165.3
- switch to difflib.diff_bytes and sys.stdout.buffer.write for diffing.
This will fix all decoding issues with osc diff, osc ci and osc rq -d
- fix osc ls -lb handling empty size and mtime
- removed decoding on osc api command.
- fixed broken TLS certificate handling (boo#1142518, CVE-2019-3685)
0.165.2 0.165.2
- support different token operations (runservice, release and rebuild) (requires OBS 2.10) - support different token operations (runservice, release and rebuild) (requires OBS 2.10)

View File

@@ -30,7 +30,8 @@ try:
from rpm import error as RPMError from rpm import error as RPMError
except: except:
# if rpm-python isn't installed (we might be on a debian system): # if rpm-python isn't installed (we might be on a debian system):
RPMError = None class RPMError(Exception):
pass
try: try:
from http.client import HTTPException, BadStatusLine from http.client import HTTPException, BadStatusLine

View File

@@ -1409,16 +1409,19 @@ Please submit there instead, or use --nodevelproject to force direct submission.
rdiff = None rdiff = None
if opts.diff or not opts.message: if opts.diff or not opts.message:
try: try:
rdiff = 'old: %s/%s\nnew: %s/%s rev %s\n' % (dst_project, dst_package, src_project, src_package, rev) rdiff = b'old: %s/%s\nnew: %s/%s rev %s\n' % (dst_project.encode(), dst_package.encode(), src_project.encode(), src_package.encode(), str(rev).encode())
rdiff += decode_it(server_diff(apiurl, rdiff += server_diff(apiurl,
dst_project, dst_package, None, dst_project, dst_package, None,
src_project, src_package, rev, True)) src_project, src_package, rev, True)
except: except:
rdiff = '' rdiff = b''
if opts.diff: if opts.diff:
run_pager(rdiff) run_pager(rdiff)
return return
if rdiff is not None:
rdiff = decode_it(rdiff)
supersede_existing = False supersede_existing = False
reqs = [] reqs = []
if not opts.supersede: if not opts.supersede:
@@ -1514,13 +1517,13 @@ Please submit there instead, or use --nodevelproject to force direct submission.
sys.exit("Please fix this first") sys.exit("Please fix this first")
t = linkinfo.get('project') t = linkinfo.get('project')
if t: if t:
rdiff = '' rdiff = b''
try: try:
rdiff = server_diff(apiurl, t, p, opts.revision, project, p, None, True) rdiff = server_diff(apiurl, t, p, opts.revision, project, p, None, True)
except: except:
rdiff = '' rdiff = b''
if rdiff != '': if rdiff != b'':
targetprojects.append(t) targetprojects.append(t)
pac.append(p) pac.append(p)
else: else:
@@ -2499,10 +2502,10 @@ Please submit there instead, or use --nodevelproject to force direct submission.
if not r.get_actions('submit') and not r.get_actions('maintenance_incident') and not r.get_actions('maintenance_release'): if not r.get_actions('submit') and not r.get_actions('maintenance_incident') and not r.get_actions('maintenance_release'):
raise oscerr.WrongOptions('\'--diff\' not possible (request has no supported actions)') raise oscerr.WrongOptions('\'--diff\' not possible (request has no supported actions)')
for action in sr_actions: for action in sr_actions:
diff += 'old: %s/%s\nnew: %s/%s\n' % (action.src_project, action.src_package, diff += b'old: %s/%s\nnew: %s/%s\n' % (action.src_project.encode(), action.src_package.encode(),
action.tgt_project, action.tgt_package) action.tgt_project.encode(), action.tgt_package.encode())
diff += submit_action_diff(apiurl, action) diff += submit_action_diff(apiurl, action)
diff += '\n\n' diff += b'\n\n'
run_pager(decode_it(diff), tmp_suffix='') run_pager(decode_it(diff), tmp_suffix='')
# checkout # checkout
@@ -3870,15 +3873,15 @@ Please submit there instead, or use --nodevelproject to force direct submission.
return return
else: else:
rev1, rev2 = parseRevisionOption(opts.revision) rev1, rev2 = parseRevisionOption(opts.revision)
diff = '' diff = b''
for pac in pacs: for pac in pacs:
if not rev2: if not rev2:
for i in pac.get_diff(rev1): for i in pac.get_diff(rev1):
diff += ''.join(i) diff += b''.join(i)
else: else:
diff += decode_it(server_diff_noex(pac.apiurl, pac.prjname, pac.name, rev1, diff += server_diff_noex(pac.apiurl, pac.prjname, pac.name, rev1,
pac.prjname, pac.name, rev2, pac.prjname, pac.name, rev2,
not opts.plain, opts.missingok, opts.meta, not opts.unexpand)) not opts.plain, opts.missingok, opts.meta, not opts.unexpand)
run_pager(diff) run_pager(diff)
@@ -4162,7 +4165,13 @@ Please submit there instead, or use --nodevelproject to force direct submission.
print("".join(decode_it(x) for x in p.stdout.readlines())) print("".join(decode_it(x) for x in p.stdout.readlines()))
elif opts.unified: elif opts.unified:
print() print()
print(decode_it(rdiff)) if isinstance(rdiff, str):
print(rdiff)
else:
try:
sys.stdout.buffer.write(rdiff)
except AttributeError as e:
print(decode_it(rdiff))
#run_pager(rdiff) #run_pager(rdiff)
def _prdiff_output_matching_requests(self, opts, requests, def _prdiff_output_matching_requests(self, opts, requests,

View File

@@ -5,7 +5,7 @@
from __future__ import print_function from __future__ import print_function
__version__ = '0.165.3.git' __version__ = '0.166.git'
# __store_version__ is to be incremented when the format of the working copy # __store_version__ is to be incremented when the format of the working copy
# "store" changes in an incompatible way. Please add any needed migration # "store" changes in an incompatible way. Please add any needed migration
@@ -1963,26 +1963,30 @@ class Package:
def get_diff(self, revision=None, ignoreUnversioned=False): def get_diff(self, revision=None, ignoreUnversioned=False):
import tempfile import tempfile
diff_hdr = 'Index: %s\n' diff_hdr = b'Index: %s\n'
diff_hdr += '===================================================================\n' diff_hdr += b'===================================================================\n'
kept = [] kept = []
added = [] added = []
deleted = [] deleted = []
def diff_add_delete(fname, add, revision): def diff_add_delete(fname, add, revision):
diff = [] diff = []
diff.append(diff_hdr % fname) diff.append(diff_hdr % fname.encode())
tmpfile = None tmpfile = None
origname = fname origname = fname
if add: if add:
diff.append('--- %s\t(revision 0)\n' % fname) diff.append(b'--- %s\t(revision 0)\n' % fname.encode())
rev = 'revision 0' rev = 'revision 0'
if revision and not fname in self.to_be_added: if revision and not fname in self.to_be_added:
rev = 'working copy' rev = 'working copy'
diff.append('+++ %s\t(%s)\n' % (fname, rev)) diff.append(b'+++ %s\t(%s)\n' % (fname.encode(), rev.encode()))
fname = os.path.join(self.absdir, fname) fname = os.path.join(self.absdir, fname)
else: else:
diff.append('--- %s\t(revision %s)\n' % (fname, revision or self.rev)) if revision:
diff.append('+++ %s\t(working copy)\n' % fname) b_revision = str(revision).encode()
else:
b_revision = self.rev.encode()
diff.append(b'--- %s\t(revision %s)\n' % (fname.encode(), b_revision))
diff.append(b'+++ %s\t(working copy)\n' % fname.encode())
fname = os.path.join(self.storedir, fname) fname = os.path.join(self.storedir, fname)
try: try:
@@ -1991,22 +1995,22 @@ class Package:
get_source_file(self.apiurl, self.prjname, self.name, origname, tmpfile, revision) get_source_file(self.apiurl, self.prjname, self.name, origname, tmpfile, revision)
fname = tmpfile fname = tmpfile
if binary_file(fname): if binary_file(fname):
what = 'added' what = b'added'
if not add: if not add:
what = 'deleted' what = b'deleted'
diff = diff[:1] diff = diff[:1]
diff.append('Binary file \'%s\' %s.\n' % (origname, what)) diff.append(b'Binary file \'%s\' %s.\n' % (origname.encode(), what))
return diff return diff
tmpl = '+%s' tmpl = b'+%s'
ltmpl = '@@ -0,0 +1,%d @@\n' ltmpl = b'@@ -0,0 +1,%d @@\n'
if not add: if not add:
tmpl = '-%s' tmpl = b'-%s'
ltmpl = '@@ -1,%d +0,0 @@\n' ltmpl = b'@@ -1,%d +0,0 @@\n'
lines = [tmpl % i for i in open(fname, 'r').readlines()] lines = [tmpl % i for i in open(fname, 'rb').readlines()]
if len(lines): if len(lines):
diff.append(ltmpl % len(lines)) diff.append(ltmpl % len(lines))
if not lines[-1].endswith('\n'): if not lines[-1].endswith(b'\n'):
lines.append('\n\\ No newline at end of file\n') lines.append(b'\n\\ No newline at end of file\n')
diff.extend(lines) diff.extend(lines)
finally: finally:
if tmpfile is not None: if tmpfile is not None:
@@ -2051,7 +2055,7 @@ class Package:
continue continue
elif revision and self.findfilebyname(f.name).md5 == f.md5 and state != 'M': elif revision and self.findfilebyname(f.name).md5 == f.md5 and state != 'M':
continue continue
yield [diff_hdr % f.name] yield [diff_hdr % f.name.encode()]
if revision is None: if revision is None:
yield get_source_file_diff(self.absdir, f.name, self.rev) yield get_source_file_diff(self.absdir, f.name, self.rev)
else: else:
@@ -4055,7 +4059,7 @@ def run_pager(message, tmp_suffix=''):
if isinstance(message, str): if isinstance(message, str):
print(message) print(message)
else: else:
print(decode_it(message)) sys.stdout.buffer.write(message)
else: else:
tmpfile = tempfile.NamedTemporaryFile(suffix=tmp_suffix) tmpfile = tempfile.NamedTemporaryFile(suffix=tmp_suffix)
if isinstance(message, str): if isinstance(message, str):
@@ -4780,15 +4784,15 @@ def get_source_file_diff(dir, filename, rev, oldfilename = None, olddir = None,
file1 = os.path.join(olddir, oldfilename) # old/stored original file1 = os.path.join(olddir, oldfilename) # old/stored original
file2 = os.path.join(dir, filename) # working copy file2 = os.path.join(dir, filename) # working copy
if binary_file(file1) or binary_file(file2): if binary_file(file1) or binary_file(file2):
return ['Binary file \'%s\' has changed.\n' % origfilename] return [b'Binary file \'%s\' has changed.\n' % origfilename.encode()]
f1 = f2 = None f1 = f2 = None
try: try:
f1 = open(file1, 'rt') f1 = open(file1, 'rb')
s1 = f1.readlines() s1 = f1.readlines()
f1.close() f1.close()
f2 = open(file2, 'rt') f2 = open(file2, 'rb')
s2 = f2.readlines() s2 = f2.readlines()
f2.close() f2.close()
finally: finally:
@@ -4796,23 +4800,31 @@ def get_source_file_diff(dir, filename, rev, oldfilename = None, olddir = None,
f1.close() f1.close()
if f2: if f2:
f2.close() f2.close()
from_file = b'%s\t(revision %s)' % (origfilename.encode(), str(rev).encode())
to_file = b'%s\t(working copy)' % origfilename.encode()
d = difflib.unified_diff(s1, s2, if sys.version_info < (3,0):
fromfile = '%s\t(revision %s)' % (origfilename, rev), \ d = difflib.unified_diff(s1, s2,
tofile = '%s\t(working copy)' % origfilename) fromfile = from_file, \
tofile = to_file)
else:
d = difflib.diff_bytes(difflib.unified_diff, s1, s2, \
fromfile = from_file, \
tofile = to_file)
d = list(d) d = list(d)
# python2.7's difflib slightly changed the format # python2.7's difflib slightly changed the format
# adapt old format to the new format # adapt old format to the new format
if len(d) > 1: if len(d) > 1:
d[0] = d[0].replace(' \n', '\n') d[0] = d[0].replace(b' \n', b'\n')
d[1] = d[1].replace(' \n', '\n') d[1] = d[1].replace(b' \n', b'\n')
# if file doesn't end with newline, we need to append one in the diff result # if file doesn't end with newline, we need to append one in the diff result
for i, line in enumerate(d): for i, line in enumerate(d):
if not line.endswith('\n'): if not line.endswith(b'\n'):
d[i] += '\n\\ No newline at end of file' d[i] += b'\n\\ No newline at end of file'
if i+1 != len(d): if i+1 != len(d):
d[i] += '\n' d[i] += b'\n'
return d return d
def server_diff(apiurl, def server_diff(apiurl,
@@ -4868,14 +4880,14 @@ def server_diff_noex(apiurl,
msg = None msg = None
body = None body = None
try: try:
body = decode_it(e.read()) body = e.read()
if not 'bad link' in body: if not b'bad link' in body:
return '# diff failed: ' + body return b'# diff failed: ' + body
except: except:
return '# diff failed with unknown error' return b'# diff failed with unknown error'
if expand: if expand:
rdiff = "## diff on expanded link not possible, showing unexpanded version\n" rdiff = b"## diff on expanded link not possible, showing unexpanded version\n"
try: try:
rdiff += server_diff_noex(apiurl, rdiff += server_diff_noex(apiurl,
old_project, old_package, old_revision, old_project, old_package, old_revision,
@@ -4886,7 +4898,7 @@ def server_diff_noex(apiurl,
summary = '' summary = ''
if not elm is None: if not elm is None:
summary = elm.text summary = elm.text
return 'error: diffing failed: %s' % summary return b'error: diffing failed: %s' % summary.encode()
return rdiff return rdiff
@@ -4935,10 +4947,10 @@ def submit_action_diff(apiurl, action):
if e.code != 404: if e.code != 404:
raise e raise e
root = ET.fromstring(e.read()) root = ET.fromstring(e.read())
return 'error: \'%s\' does not exist' % root.find('summary').text return b'error: \'%s\' does not exist' % root.find('summary').text.encode()
elif e.code == 404: elif e.code == 404:
root = ET.fromstring(e.read()) root = ET.fromstring(e.read())
return 'error: \'%s\' does not exist' % root.find('summary').text return b'error: \'%s\' does not exist' % root.find('summary').text.encode()
raise e raise e
def make_dir(apiurl, project, package, pathname=None, prj_dir=None, package_tracking=True, pkg_path=None): def make_dir(apiurl, project, package, pathname=None, prj_dir=None, package_tracking=True, pkg_path=None):
@@ -7249,13 +7261,11 @@ def get_commit_message_template(pac):
if pac.status(filename) == 'M': if pac.status(filename) == 'M':
diff += get_source_file_diff(pac.absdir, filename, pac.rev) diff += get_source_file_diff(pac.absdir, filename, pac.rev)
elif pac.status(filename) == 'A': elif pac.status(filename) == 'A':
f = open(os.path.join(pac.absdir, filename), 'r') with open(os.path.join(pac.absdir, filename), 'rb') as f:
for line in f: diff.extend((b'+' + line for line in f))
diff += '+' + line
f.close()
if diff: if diff:
template = parse_diff_for_commit_message(''.join(diff)) template = parse_diff_for_commit_message(''.join(decode_list(diff)))
return template return template
@@ -7290,7 +7300,7 @@ def get_commit_msg(wc_dir, pacs):
if changed: if changed:
footer += changed footer += changed
footer.append('\nDiff for working copy: %s' % p.dir) footer.append('\nDiff for working copy: %s' % p.dir)
footer.extend([''.join(i) for i in p.get_diff(ignoreUnversioned=True)]) footer.extend([''.join(decode_list(i)) for i in p.get_diff(ignoreUnversioned=True)])
lines.extend(get_commit_message_template(p)) lines.extend(get_commit_message_template(p))
if template is None: if template is None:
if lines and lines[0] == '': if lines and lines[0] == '':
@@ -7440,21 +7450,21 @@ def request_interactive_review(apiurl, request, initial_cmd='', group=None,
tmpfile.close() tmpfile.close()
tmpfile = None tmpfile = None
if tmpfile is None: if tmpfile is None:
tmpfile = tempfile.NamedTemporaryFile(suffix='.diff', mode='r+') tmpfile = tempfile.NamedTemporaryFile(suffix='.diff', mode='rb+')
tmpfile.write(req_summary) tmpfile.write(req_summary.encode())
tmpfile.write(issues) tmpfile.write(issues.encode())
try: try:
diff = request_diff(apiurl, request.reqid) diff = request_diff(apiurl, request.reqid)
tmpfile.write(decode_it(diff)) tmpfile.write(diff)
except HTTPError as e: except HTTPError as e:
if e.code != 400: if e.code != 400:
raise raise
# backward compatible diff for old apis # backward compatible diff for old apis
for action in src_actions: for action in src_actions:
diff = 'old: %s/%s\nnew: %s/%s\n' % (action.src_project, action.src_package, diff = b'old: %s/%s\nnew: %s/%s\n' % (action.src_project.encode(), action.src_package.encode(),
action.tgt_project, action.tgt_package) action.tgt_project.encode(), action.tgt_package.encode())
diff += submit_action_diff(apiurl, action) diff += submit_action_diff(apiurl, action)
diff += '\n\n' diff += b'\n\n'
tmpfile.write(diff) tmpfile.write(diff)
tmpfile.flush() tmpfile.flush()
run_editor(tmpfile.name) run_editor(tmpfile.name)

View File

@@ -199,13 +199,13 @@ class myHTTPSHandler(M2Crypto.m2urllib2.HTTPSHandler):
if target_host != host: if target_host != host:
request_uri = urldefrag(full_url)[0] request_uri = urldefrag(full_url)[0]
h = httpslib.ProxyHTTPSConnection(host=host, ssl_context=self.ctx) h = myProxyHTTPSConnection(host=host, ssl_context=self.ctx)
else: else:
try: # up to python-3.2 try: # up to python-3.2
request_uri = req.get_selector() request_uri = req.get_selector()
except AttributeError: # from python-3.3 except AttributeError: # from python-3.3
request_uri = req.selector request_uri = req.selector
h = httpslib.HTTPSConnection(host=host, ssl_context=self.ctx) h = myHTTPSConnection(host=host, ssl_context=self.ctx)
# End our change # End our change
h.set_debuglevel(self._debuglevel) h.set_debuglevel(self._debuglevel)

View File

@@ -1,5 +1,6 @@
import osc.core import osc.core
import osc.oscerr import osc.oscerr
from osc.util.helper import decode_list
import os import os
import re import re
from common import GET, OscTestCase from common import GET, OscTestCase
@@ -298,7 +299,7 @@ Binary file 'binary' has changed.
def __check_diff(self, p, exp, revision=None): def __check_diff(self, p, exp, revision=None):
got = '' got = ''
for i in p.get_diff(revision): for i in p.get_diff(revision):
got += ''.join(i) got += ''.join(decode_list(i))
# When a hunk header refers to a single line in the "from" # When a hunk header refers to a single line in the "from"
# file and/or the "to" file, e.g. # file and/or the "to" file, e.g.