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