Edit File by line
/home/barbar84/www/wp-conte.../plugins/sujqvwi/AnonR/smanonr..../lib64/python3....
File: quopri.py
#! /usr/bin/python3.8
[0] Fix | Delete
[1] Fix | Delete
"""Conversions to/from quoted-printable transport encoding as per RFC 1521."""
[2] Fix | Delete
[3] Fix | Delete
# (Dec 1991 version).
[4] Fix | Delete
[5] Fix | Delete
__all__ = ["encode", "decode", "encodestring", "decodestring"]
[6] Fix | Delete
[7] Fix | Delete
ESCAPE = b'='
[8] Fix | Delete
MAXLINESIZE = 76
[9] Fix | Delete
HEX = b'0123456789ABCDEF'
[10] Fix | Delete
EMPTYSTRING = b''
[11] Fix | Delete
[12] Fix | Delete
try:
[13] Fix | Delete
from binascii import a2b_qp, b2a_qp
[14] Fix | Delete
except ImportError:
[15] Fix | Delete
a2b_qp = None
[16] Fix | Delete
b2a_qp = None
[17] Fix | Delete
[18] Fix | Delete
[19] Fix | Delete
def needsquoting(c, quotetabs, header):
[20] Fix | Delete
"""Decide whether a particular byte ordinal needs to be quoted.
[21] Fix | Delete
[22] Fix | Delete
The 'quotetabs' flag indicates whether embedded tabs and spaces should be
[23] Fix | Delete
quoted. Note that line-ending tabs and spaces are always encoded, as per
[24] Fix | Delete
RFC 1521.
[25] Fix | Delete
"""
[26] Fix | Delete
assert isinstance(c, bytes)
[27] Fix | Delete
if c in b' \t':
[28] Fix | Delete
return quotetabs
[29] Fix | Delete
# if header, we have to escape _ because _ is used to escape space
[30] Fix | Delete
if c == b'_':
[31] Fix | Delete
return header
[32] Fix | Delete
return c == ESCAPE or not (b' ' <= c <= b'~')
[33] Fix | Delete
[34] Fix | Delete
def quote(c):
[35] Fix | Delete
"""Quote a single character."""
[36] Fix | Delete
assert isinstance(c, bytes) and len(c)==1
[37] Fix | Delete
c = ord(c)
[38] Fix | Delete
return ESCAPE + bytes((HEX[c//16], HEX[c%16]))
[39] Fix | Delete
[40] Fix | Delete
[41] Fix | Delete
[42] Fix | Delete
def encode(input, output, quotetabs, header=False):
[43] Fix | Delete
"""Read 'input', apply quoted-printable encoding, and write to 'output'.
[44] Fix | Delete
[45] Fix | Delete
'input' and 'output' are binary file objects. The 'quotetabs' flag
[46] Fix | Delete
indicates whether embedded tabs and spaces should be quoted. Note that
[47] Fix | Delete
line-ending tabs and spaces are always encoded, as per RFC 1521.
[48] Fix | Delete
The 'header' flag indicates whether we are encoding spaces as _ as per RFC
[49] Fix | Delete
1522."""
[50] Fix | Delete
[51] Fix | Delete
if b2a_qp is not None:
[52] Fix | Delete
data = input.read()
[53] Fix | Delete
odata = b2a_qp(data, quotetabs=quotetabs, header=header)
[54] Fix | Delete
output.write(odata)
[55] Fix | Delete
return
[56] Fix | Delete
[57] Fix | Delete
def write(s, output=output, lineEnd=b'\n'):
[58] Fix | Delete
# RFC 1521 requires that the line ending in a space or tab must have
[59] Fix | Delete
# that trailing character encoded.
[60] Fix | Delete
if s and s[-1:] in b' \t':
[61] Fix | Delete
output.write(s[:-1] + quote(s[-1:]) + lineEnd)
[62] Fix | Delete
elif s == b'.':
[63] Fix | Delete
output.write(quote(s) + lineEnd)
[64] Fix | Delete
else:
[65] Fix | Delete
output.write(s + lineEnd)
[66] Fix | Delete
[67] Fix | Delete
prevline = None
[68] Fix | Delete
while 1:
[69] Fix | Delete
line = input.readline()
[70] Fix | Delete
if not line:
[71] Fix | Delete
break
[72] Fix | Delete
outline = []
[73] Fix | Delete
# Strip off any readline induced trailing newline
[74] Fix | Delete
stripped = b''
[75] Fix | Delete
if line[-1:] == b'\n':
[76] Fix | Delete
line = line[:-1]
[77] Fix | Delete
stripped = b'\n'
[78] Fix | Delete
# Calculate the un-length-limited encoded line
[79] Fix | Delete
for c in line:
[80] Fix | Delete
c = bytes((c,))
[81] Fix | Delete
if needsquoting(c, quotetabs, header):
[82] Fix | Delete
c = quote(c)
[83] Fix | Delete
if header and c == b' ':
[84] Fix | Delete
outline.append(b'_')
[85] Fix | Delete
else:
[86] Fix | Delete
outline.append(c)
[87] Fix | Delete
# First, write out the previous line
[88] Fix | Delete
if prevline is not None:
[89] Fix | Delete
write(prevline)
[90] Fix | Delete
# Now see if we need any soft line breaks because of RFC-imposed
[91] Fix | Delete
# length limitations. Then do the thisline->prevline dance.
[92] Fix | Delete
thisline = EMPTYSTRING.join(outline)
[93] Fix | Delete
while len(thisline) > MAXLINESIZE:
[94] Fix | Delete
# Don't forget to include the soft line break `=' sign in the
[95] Fix | Delete
# length calculation!
[96] Fix | Delete
write(thisline[:MAXLINESIZE-1], lineEnd=b'=\n')
[97] Fix | Delete
thisline = thisline[MAXLINESIZE-1:]
[98] Fix | Delete
# Write out the current line
[99] Fix | Delete
prevline = thisline
[100] Fix | Delete
# Write out the last line, without a trailing newline
[101] Fix | Delete
if prevline is not None:
[102] Fix | Delete
write(prevline, lineEnd=stripped)
[103] Fix | Delete
[104] Fix | Delete
def encodestring(s, quotetabs=False, header=False):
[105] Fix | Delete
if b2a_qp is not None:
[106] Fix | Delete
return b2a_qp(s, quotetabs=quotetabs, header=header)
[107] Fix | Delete
from io import BytesIO
[108] Fix | Delete
infp = BytesIO(s)
[109] Fix | Delete
outfp = BytesIO()
[110] Fix | Delete
encode(infp, outfp, quotetabs, header)
[111] Fix | Delete
return outfp.getvalue()
[112] Fix | Delete
[113] Fix | Delete
[114] Fix | Delete
[115] Fix | Delete
def decode(input, output, header=False):
[116] Fix | Delete
"""Read 'input', apply quoted-printable decoding, and write to 'output'.
[117] Fix | Delete
'input' and 'output' are binary file objects.
[118] Fix | Delete
If 'header' is true, decode underscore as space (per RFC 1522)."""
[119] Fix | Delete
[120] Fix | Delete
if a2b_qp is not None:
[121] Fix | Delete
data = input.read()
[122] Fix | Delete
odata = a2b_qp(data, header=header)
[123] Fix | Delete
output.write(odata)
[124] Fix | Delete
return
[125] Fix | Delete
[126] Fix | Delete
new = b''
[127] Fix | Delete
while 1:
[128] Fix | Delete
line = input.readline()
[129] Fix | Delete
if not line: break
[130] Fix | Delete
i, n = 0, len(line)
[131] Fix | Delete
if n > 0 and line[n-1:n] == b'\n':
[132] Fix | Delete
partial = 0; n = n-1
[133] Fix | Delete
# Strip trailing whitespace
[134] Fix | Delete
while n > 0 and line[n-1:n] in b" \t\r":
[135] Fix | Delete
n = n-1
[136] Fix | Delete
else:
[137] Fix | Delete
partial = 1
[138] Fix | Delete
while i < n:
[139] Fix | Delete
c = line[i:i+1]
[140] Fix | Delete
if c == b'_' and header:
[141] Fix | Delete
new = new + b' '; i = i+1
[142] Fix | Delete
elif c != ESCAPE:
[143] Fix | Delete
new = new + c; i = i+1
[144] Fix | Delete
elif i+1 == n and not partial:
[145] Fix | Delete
partial = 1; break
[146] Fix | Delete
elif i+1 < n and line[i+1:i+2] == ESCAPE:
[147] Fix | Delete
new = new + ESCAPE; i = i+2
[148] Fix | Delete
elif i+2 < n and ishex(line[i+1:i+2]) and ishex(line[i+2:i+3]):
[149] Fix | Delete
new = new + bytes((unhex(line[i+1:i+3]),)); i = i+3
[150] Fix | Delete
else: # Bad escape sequence -- leave it in
[151] Fix | Delete
new = new + c; i = i+1
[152] Fix | Delete
if not partial:
[153] Fix | Delete
output.write(new + b'\n')
[154] Fix | Delete
new = b''
[155] Fix | Delete
if new:
[156] Fix | Delete
output.write(new)
[157] Fix | Delete
[158] Fix | Delete
def decodestring(s, header=False):
[159] Fix | Delete
if a2b_qp is not None:
[160] Fix | Delete
return a2b_qp(s, header=header)
[161] Fix | Delete
from io import BytesIO
[162] Fix | Delete
infp = BytesIO(s)
[163] Fix | Delete
outfp = BytesIO()
[164] Fix | Delete
decode(infp, outfp, header=header)
[165] Fix | Delete
return outfp.getvalue()
[166] Fix | Delete
[167] Fix | Delete
[168] Fix | Delete
[169] Fix | Delete
# Other helper functions
[170] Fix | Delete
def ishex(c):
[171] Fix | Delete
"""Return true if the byte ordinal 'c' is a hexadecimal digit in ASCII."""
[172] Fix | Delete
assert isinstance(c, bytes)
[173] Fix | Delete
return b'0' <= c <= b'9' or b'a' <= c <= b'f' or b'A' <= c <= b'F'
[174] Fix | Delete
[175] Fix | Delete
def unhex(s):
[176] Fix | Delete
"""Get the integer value of a hexadecimal number."""
[177] Fix | Delete
bits = 0
[178] Fix | Delete
for c in s:
[179] Fix | Delete
c = bytes((c,))
[180] Fix | Delete
if b'0' <= c <= b'9':
[181] Fix | Delete
i = ord('0')
[182] Fix | Delete
elif b'a' <= c <= b'f':
[183] Fix | Delete
i = ord('a')-10
[184] Fix | Delete
elif b'A' <= c <= b'F':
[185] Fix | Delete
i = ord(b'A')-10
[186] Fix | Delete
else:
[187] Fix | Delete
assert False, "non-hex digit "+repr(c)
[188] Fix | Delete
bits = bits*16 + (ord(c) - i)
[189] Fix | Delete
return bits
[190] Fix | Delete
[191] Fix | Delete
[192] Fix | Delete
[193] Fix | Delete
def main():
[194] Fix | Delete
import sys
[195] Fix | Delete
import getopt
[196] Fix | Delete
try:
[197] Fix | Delete
opts, args = getopt.getopt(sys.argv[1:], 'td')
[198] Fix | Delete
except getopt.error as msg:
[199] Fix | Delete
sys.stdout = sys.stderr
[200] Fix | Delete
print(msg)
[201] Fix | Delete
print("usage: quopri [-t | -d] [file] ...")
[202] Fix | Delete
print("-t: quote tabs")
[203] Fix | Delete
print("-d: decode; default encode")
[204] Fix | Delete
sys.exit(2)
[205] Fix | Delete
deco = 0
[206] Fix | Delete
tabs = 0
[207] Fix | Delete
for o, a in opts:
[208] Fix | Delete
if o == '-t': tabs = 1
[209] Fix | Delete
if o == '-d': deco = 1
[210] Fix | Delete
if tabs and deco:
[211] Fix | Delete
sys.stdout = sys.stderr
[212] Fix | Delete
print("-t and -d are mutually exclusive")
[213] Fix | Delete
sys.exit(2)
[214] Fix | Delete
if not args: args = ['-']
[215] Fix | Delete
sts = 0
[216] Fix | Delete
for file in args:
[217] Fix | Delete
if file == '-':
[218] Fix | Delete
fp = sys.stdin.buffer
[219] Fix | Delete
else:
[220] Fix | Delete
try:
[221] Fix | Delete
fp = open(file, "rb")
[222] Fix | Delete
except OSError as msg:
[223] Fix | Delete
sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
[224] Fix | Delete
sts = 1
[225] Fix | Delete
continue
[226] Fix | Delete
try:
[227] Fix | Delete
if deco:
[228] Fix | Delete
decode(fp, sys.stdout.buffer)
[229] Fix | Delete
else:
[230] Fix | Delete
encode(fp, sys.stdout.buffer, tabs)
[231] Fix | Delete
finally:
[232] Fix | Delete
if file != '-':
[233] Fix | Delete
fp.close()
[234] Fix | Delete
if sts:
[235] Fix | Delete
sys.exit(sts)
[236] Fix | Delete
[237] Fix | Delete
[238] Fix | Delete
[239] Fix | Delete
if __name__ == '__main__':
[240] Fix | Delete
main()
[241] Fix | Delete
[242] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function