diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2000-10-05 17:24:33 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2000-10-05 17:24:33 (GMT) |
commit | 77249442a58b4afb561f7c8290d63bea85126d9d (patch) | |
tree | ccb24371df716b52fc58250c48b5e0ec207c893b /Lib/quopri.py | |
parent | 9351dd2084262b67d58f2dc7c084bf48353f587d (diff) | |
download | cpython-77249442a58b4afb561f7c8290d63bea85126d9d.zip cpython-77249442a58b4afb561f7c8290d63bea85126d9d.tar.gz cpython-77249442a58b4afb561f7c8290d63bea85126d9d.tar.bz2 |
Fix Bug #115907: encode '=' as '=3D' and not '=='
Diffstat (limited to 'Lib/quopri.py')
-rwxr-xr-x | Lib/quopri.py | 243 |
1 files changed, 122 insertions, 121 deletions
diff --git a/Lib/quopri.py b/Lib/quopri.py index cd2f5eb..b449792 100755 --- a/Lib/quopri.py +++ b/Lib/quopri.py @@ -9,141 +9,142 @@ MAXLINESIZE = 76 HEX = '0123456789ABCDEF' def needsquoting(c, quotetabs): - """Decide whether a particular character needs to be quoted. + """Decide whether a particular character needs to be quoted. - The 'quotetabs' flag indicates whether tabs should be quoted.""" - if c == '\t': - return not quotetabs - return c == ESCAPE or not(' ' <= c <= '~') + The 'quotetabs' flag indicates whether tabs should be quoted.""" + if c == '\t': + return not quotetabs + return c == ESCAPE or not(' ' <= c <= '~') def quote(c): - """Quote a single character.""" - if c == ESCAPE: - return ESCAPE * 2 - else: - i = ord(c) - return ESCAPE + HEX[i/16] + HEX[i%16] + """Quote a single character.""" + i = ord(c) + return ESCAPE + HEX[i/16] + HEX[i%16] def encode(input, output, quotetabs): - """Read 'input', apply quoted-printable encoding, and write to 'output'. + """Read 'input', apply quoted-printable encoding, and write to 'output'. - 'input' and 'output' are files with readline() and write() methods. - The 'quotetabs' flag indicates whether tabs should be quoted.""" - while 1: - line = input.readline() - if not line: break - new = '' - last = line[-1:] - if last == '\n': line = line[:-1] - else: last = '' - prev = '' - for c in line: - if needsquoting(c, quotetabs): - c = quote(c) - if len(new) + len(c) >= MAXLINESIZE: - output.write(new + ESCAPE + '\n') - new = '' - new = new + c - prev = c - if prev in (' ', '\t'): - output.write(new + ESCAPE + '\n\n') - else: - output.write(new + '\n') + 'input' and 'output' are files with readline() and write() methods. + The 'quotetabs' flag indicates whether tabs should be quoted. + """ + while 1: + line = input.readline() + if not line: + break + new = '' + last = line[-1:] + if last == '\n': + line = line[:-1] + else: + last = '' + prev = '' + for c in line: + if needsquoting(c, quotetabs): + c = quote(c) + if len(new) + len(c) >= MAXLINESIZE: + output.write(new + ESCAPE + '\n') + new = '' + new = new + c + prev = c + if prev in (' ', '\t'): + output.write(new + ESCAPE + '\n\n') + else: + output.write(new + '\n') def decode(input, output): - """Read 'input', apply quoted-printable decoding, and write to 'output'. + """Read 'input', apply quoted-printable decoding, and write to 'output'. - 'input' and 'output' are files with readline() and write() methods.""" - new = '' - while 1: - line = input.readline() - if not line: break - i, n = 0, len(line) - if n > 0 and line[n-1] == '\n': - partial = 0; n = n-1 - # Strip trailing whitespace - while n > 0 and line[n-1] in (' ', '\t'): - n = n-1 - else: - partial = 1 - while i < n: - c = line[i] - if c <> ESCAPE: - new = new + c; i = i+1 - elif i+1 == n and not partial: - partial = 1; break - elif i+1 < n and line[i+1] == ESCAPE: - new = new + ESCAPE; i = i+2 - elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]): - new = new + chr(unhex(line[i+1:i+3])); i = i+3 - else: # Bad escape sequence -- leave it in - new = new + c; i = i+1 - if not partial: - output.write(new + '\n') - new = '' - if new: - output.write(new) + 'input' and 'output' are files with readline() and write() methods.""" + new = '' + while 1: + line = input.readline() + if not line: break + i, n = 0, len(line) + if n > 0 and line[n-1] == '\n': + partial = 0; n = n-1 + # Strip trailing whitespace + while n > 0 and line[n-1] in (' ', '\t'): + n = n-1 + else: + partial = 1 + while i < n: + c = line[i] + if c <> ESCAPE: + new = new + c; i = i+1 + elif i+1 == n and not partial: + partial = 1; break + elif i+1 < n and line[i+1] == ESCAPE: + new = new + ESCAPE; i = i+2 + elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]): + new = new + chr(unhex(line[i+1:i+3])); i = i+3 + else: # Bad escape sequence -- leave it in + new = new + c; i = i+1 + if not partial: + output.write(new + '\n') + new = '' + if new: + output.write(new) def ishex(c): - """Return true if the character 'c' is a hexadecimal digit.""" - return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F' + """Return true if the character 'c' is a hexadecimal digit.""" + return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F' def unhex(s): - """Get the integer value of a hexadecimal number.""" - bits = 0 - for c in s: - if '0' <= c <= '9': - i = ord('0') - elif 'a' <= c <= 'f': - i = ord('a')-10 - elif 'A' <= c <= 'F': - i = ord('A')-10 - else: - break - bits = bits*16 + (ord(c) - i) - return bits + """Get the integer value of a hexadecimal number.""" + bits = 0 + for c in s: + if '0' <= c <= '9': + i = ord('0') + elif 'a' <= c <= 'f': + i = ord('a')-10 + elif 'A' <= c <= 'F': + i = ord('A')-10 + else: + break + bits = bits*16 + (ord(c) - i) + return bits def test(): - import sys - import getopt - try: - opts, args = getopt.getopt(sys.argv[1:], 'td') - except getopt.error, msg: - sys.stdout = sys.stderr - print msg - print "usage: quopri [-t | -d] [file] ..." - print "-t: quote tabs" - print "-d: decode; default encode" - sys.exit(2) - deco = 0 - tabs = 0 - for o, a in opts: - if o == '-t': tabs = 1 - if o == '-d': deco = 1 - if tabs and deco: - sys.stdout = sys.stderr - print "-t and -d are mutually exclusive" - sys.exit(2) - if not args: args = ['-'] - sts = 0 - for file in args: - if file == '-': - fp = sys.stdin - else: - try: - fp = open(file) - except IOError, msg: - sys.stderr.write("%s: can't open (%s)\n" % (file, msg)) - sts = 1 - continue - if deco: - decode(fp, sys.stdout) - else: - encode(fp, sys.stdout, tabs) - if fp is not sys.stdin: - fp.close() - if sts: - sys.exit(sts) + import sys + import getopt + try: + opts, args = getopt.getopt(sys.argv[1:], 'td') + except getopt.error, msg: + sys.stdout = sys.stderr + print msg + print "usage: quopri [-t | -d] [file] ..." + print "-t: quote tabs" + print "-d: decode; default encode" + sys.exit(2) + deco = 0 + tabs = 0 + for o, a in opts: + if o == '-t': tabs = 1 + if o == '-d': deco = 1 + if tabs and deco: + sys.stdout = sys.stderr + print "-t and -d are mutually exclusive" + sys.exit(2) + if not args: args = ['-'] + sts = 0 + for file in args: + if file == '-': + fp = sys.stdin + else: + try: + fp = open(file) + except IOError, msg: + sys.stderr.write("%s: can't open (%s)\n" % (file, msg)) + sts = 1 + continue + if deco: + decode(fp, sys.stdout) + else: + encode(fp, sys.stdout, tabs) + if fp is not sys.stdin: + fp.close() + if sts: + sys.exit(sts) if __name__ == '__main__': - test() + test() |