kopia lustrzana https://github.com/micropython/micropython-lib
utarfile: Fix read/write handling of nulls in tar header.
For reading, the size is always terminated by a null, so just ignore it by
using 11 for the uctypes entry (this fixes a regression introduced in
7128d423c2
).
For writing, the size must always be terminated by a null.
Signed-off-by: Damien George <damien@micropython.org>
pull/411/head
rodzic
da5ddfc6e2
commit
0a5b635594
|
@ -1,4 +1,4 @@
|
|||
metadata(description="Adds write (create/append) support to utarfile.", version="0.1")
|
||||
metadata(description="Adds write (create/append) support to utarfile.", version="0.1.1")
|
||||
|
||||
require("utarfile")
|
||||
package("utarfile")
|
||||
|
|
|
@ -11,9 +11,9 @@ import os
|
|||
# http://www.gnu.org/software/tar/manual/html_node/Standard.html
|
||||
_TAR_HEADER = {
|
||||
"name": (uctypes.ARRAY | 0, uctypes.UINT8 | 100),
|
||||
"mode": (uctypes.ARRAY | 100, uctypes.UINT8 | 7),
|
||||
"uid": (uctypes.ARRAY | 108, uctypes.UINT8 | 7),
|
||||
"gid": (uctypes.ARRAY | 116, uctypes.UINT8 | 7),
|
||||
"mode": (uctypes.ARRAY | 100, uctypes.UINT8 | 8),
|
||||
"uid": (uctypes.ARRAY | 108, uctypes.UINT8 | 8),
|
||||
"gid": (uctypes.ARRAY | 116, uctypes.UINT8 | 8),
|
||||
"size": (uctypes.ARRAY | 124, uctypes.UINT8 | 12),
|
||||
"mtime": (uctypes.ARRAY | 136, uctypes.UINT8 | 12),
|
||||
"chksum": (uctypes.ARRAY | 148, uctypes.UINT8 | 8),
|
||||
|
@ -26,12 +26,6 @@ _BLOCKSIZE = const(512) # length of processing blocks
|
|||
_RECORDSIZE = const(_BLOCKSIZE * 20) # length of records
|
||||
|
||||
|
||||
# Write a string into a bytearray by copying each byte.
|
||||
def _setstring(b, s, maxlen):
|
||||
for i, c in enumerate(s.encode("utf-8")[:maxlen]):
|
||||
b[i] = c
|
||||
|
||||
|
||||
def _open_write(self, name, mode, fileobj):
|
||||
if mode == "w":
|
||||
if not fileobj:
|
||||
|
@ -72,18 +66,18 @@ def addfile(self, tarinfo, fileobj=None):
|
|||
if not name.endswith("/"):
|
||||
name += "/"
|
||||
hdr = uctypes.struct(uctypes.addressof(buf), _TAR_HEADER, uctypes.LITTLE_ENDIAN)
|
||||
_setstring(hdr.name, name, 100)
|
||||
_setstring(hdr.mode, "%06o " % (tarinfo.mode & 0o7777), 7)
|
||||
_setstring(hdr.uid, "%06o " % tarinfo.uid, 7)
|
||||
_setstring(hdr.gid, "%06o " % tarinfo.gid, 7)
|
||||
_setstring(hdr.size, "%011o " % size, 12)
|
||||
_setstring(hdr.mtime, "%011o " % tarinfo.mtime, 12)
|
||||
_setstring(hdr.typeflag, "5" if tarinfo.isdir() else "0", 1)
|
||||
hdr.name[:] = name.encode("utf-8")[:100]
|
||||
hdr.mode[:] = b"%07o\0" % (tarinfo.mode & 0o7777)
|
||||
hdr.uid[:] = b"%07o\0" % tarinfo.uid
|
||||
hdr.gid[:] = b"%07o\0" % tarinfo.gid
|
||||
hdr.size[:] = b"%011o\0" % size
|
||||
hdr.mtime[:] = b"%011o\0" % tarinfo.mtime
|
||||
hdr.typeflag[:] = b"5" if tarinfo.isdir() else b"0"
|
||||
# Checksum is calculated with checksum field all blanks.
|
||||
_setstring(hdr.chksum, " " * 8, 8)
|
||||
hdr.chksum[:] = b" "
|
||||
# Calculate and insert the actual checksum.
|
||||
chksum = sum(buf)
|
||||
_setstring(hdr.chksum, "%06o\0" % chksum, 7)
|
||||
hdr.chksum[:] = b"%06o\0 " % chksum
|
||||
# Emit the header.
|
||||
self.f.write(buf)
|
||||
self.offset += len(buf)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
metadata(description="Read-only implementation of Python's tarfile.", version="0.4.0")
|
||||
metadata(description="Read-only implementation of Python's tarfile.", version="0.4.1")
|
||||
|
||||
# Originally written by Paul Sokolovsky.
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@ import uctypes
|
|||
|
||||
# Minimal set of tar header fields for reading.
|
||||
# http://www.gnu.org/software/tar/manual/html_node/Standard.html
|
||||
# The "size" entry is 11 (not 12) to implicitly cut off the null terminator.
|
||||
_TAR_HEADER = {
|
||||
"name": (uctypes.ARRAY | 0, uctypes.UINT8 | 100),
|
||||
"size": (uctypes.ARRAY | 124, uctypes.UINT8 | 12),
|
||||
"size": (uctypes.ARRAY | 124, uctypes.UINT8 | 11),
|
||||
}
|
||||
|
||||
DIRTYPE = const("dir")
|
||||
|
|
Ładowanie…
Reference in New Issue