Process an extended or global header as described in POSIX.1-2008.
(self, tarfile)
| 1469 | return self |
| 1470 | |
| 1471 | def _proc_pax(self, tarfile): |
| 1472 | """Process an extended or global header as described in |
| 1473 | POSIX.1-2008. |
| 1474 | """ |
| 1475 | # Read the header information. |
| 1476 | buf = tarfile.fileobj.read(self._block(self.size)) |
| 1477 | |
| 1478 | # A pax header stores supplemental information for either |
| 1479 | # the following file (extended) or all following files |
| 1480 | # (global). |
| 1481 | if self.type == XGLTYPE: |
| 1482 | pax_headers = tarfile.pax_headers |
| 1483 | else: |
| 1484 | pax_headers = tarfile.pax_headers.copy() |
| 1485 | |
| 1486 | # Parse pax header information. A record looks like that: |
| 1487 | # "%d %s=%s\n" % (length, keyword, value). length is the size |
| 1488 | # of the complete record including the length field itself and |
| 1489 | # the newline. |
| 1490 | pos = 0 |
| 1491 | encoding = None |
| 1492 | raw_headers = [] |
| 1493 | while len(buf) > pos and buf[pos] != 0x00: |
| 1494 | if not (match := _header_length_prefix_re.match(buf, pos)): |
| 1495 | raise InvalidHeaderError("invalid header") |
| 1496 | try: |
| 1497 | length = int(match.group(1)) |
| 1498 | except ValueError: |
| 1499 | raise InvalidHeaderError("invalid header") |
| 1500 | # Headers must be at least 5 bytes, shortest being '5 x=\n'. |
| 1501 | # Value is allowed to be empty. |
| 1502 | if length < 5: |
| 1503 | raise InvalidHeaderError("invalid header") |
| 1504 | if pos + length > len(buf): |
| 1505 | raise InvalidHeaderError("invalid header") |
| 1506 | |
| 1507 | header_value_end_offset = match.start(1) + length - 1 # Last byte of the header |
| 1508 | keyword_and_value = buf[match.end(1) + 1:header_value_end_offset] |
| 1509 | raw_keyword, equals, raw_value = keyword_and_value.partition(b"=") |
| 1510 | |
| 1511 | # Check the framing of the header. The last character must be '\n' (0x0A) |
| 1512 | if not raw_keyword or equals != b"=" or buf[header_value_end_offset] != 0x0A: |
| 1513 | raise InvalidHeaderError("invalid header") |
| 1514 | raw_headers.append((length, raw_keyword, raw_value)) |
| 1515 | |
| 1516 | # Check if the pax header contains a hdrcharset field. This tells us |
| 1517 | # the encoding of the path, linkpath, uname and gname fields. Normally, |
| 1518 | # these fields are UTF-8 encoded but since POSIX.1-2008 tar |
| 1519 | # implementations are allowed to store them as raw binary strings if |
| 1520 | # the translation to UTF-8 fails. For the time being, we don't care about |
| 1521 | # anything other than "BINARY". The only other value that is currently |
| 1522 | # allowed by the standard is "ISO-IR 10646 2000 UTF-8" in other words UTF-8. |
| 1523 | # Note that we only follow the initial 'hdrcharset' setting to preserve |
| 1524 | # the initial behavior of the 'tarfile' module. |
| 1525 | if raw_keyword == b"hdrcharset" and encoding is None: |
| 1526 | if raw_value == b"BINARY": |
| 1527 | encoding = tarfile.encoding |
| 1528 | else: # This branch ensures only the first 'hdrcharset' header is used. |
no test coverage detected