Skip to main content

PyPI - Python Version PyPI Package Tests codecov

Reverse packed Google Protobuf payload

Restore packed Google Protobuf message and reveal its value according to packed types. For example, you have a packed Protobuf message represented as a byte string:

# Encoded varint value -1 (signed int) or 1 (unsigned int)
08 01

By using a revpbuf package you may decode that to the following:

Field 1 - type <WireType.Varint>
	sint: -1
	uint: 1

Python code that does such a conversion:

from revpbuf import parser

proto_payload = bytes.fromhex("0801")
message_repr = parser.parse_proto(proto_payload)

Right now you have a message representation that you may print:

class Printer(BaseProtoPrinter):
    def __init__(self):
        self.level = 0

    def visit(self, ty: Union[FieldDescriptor, BaseTypeRepr]) -> str:
        if isinstance(ty, FieldDescriptor):
            return self._visit_field_descriptor(ty)
        else:
            fields = ty.get_fields()

            if not any([f for f in fields if f[0] == "sub-msg"]):
                return self._visit_non_chunk(ty, fields)
            else:
                return self._visit_chunk(ty, fields)

    def _visit_field_descriptor(self, ty: FieldDescriptor) -> str:
        tabs = "\t" * self.level
        result = f"{tabs}Field {ty.field_no} - type <{ty.wire_type}>{os.linesep}"

        return result

    def _visit_non_chunk(
        self, _ty: BaseTypeRepr, fields: Sequence[Union[str, Any]]
    ) -> str:
        tabs_field = "\t" * (self.level + 1)
        result = f"{os.linesep}".join(
            [f"{tabs_field}{field[0]}: {field[1]}" for field in fields]
        )

        return f"{result}{os.linesep}"

    def _visit_chunk(
        self, _ty: BaseTypeRepr, fields: Sequence[Union[str, Any]]
    ) -> str:
        tabs_field = "\t" * (self.level + 1)
        str_stream = io.StringIO()

        for field in fields:
            if field[0] != "sub-msg":
                result = f"{tabs_field}{field[0]}: {field[1]}{os.linesep}"
                str_stream.write(result)
            else:
                if field[1] is not None:
                    result = f"{tabs_field}{field[0]}:{os.linesep}"
                    str_stream.write(result)
                    self.level += 2

                    for sub_msg_field in field[1].fields:
                        result = sub_msg_field.field_desc.accept(self)

                        if result is not None:
                            str_stream.write(result)

                        result = sub_msg_field.field_repr.accept(self)

                        if result is not None:
                            str_stream.write(result)

                    self.level -= 2

        return str_stream.getvalue()

# ...
def proto_print(message: MessageRepr) -> str:
    printer = Printer()
    str_stream = io.StringIO()

    for field in message.fields:
        str_stream.write(field.field_desc.accept(printer))
        str_stream.write(field.field_repr.accept(printer))

    return str_stream.getvalue()

proto_print(message_repr)

That would output the example field representation above:

Field 1 - type <WireType.Varint>
	sint: -1
	uint: 1

Example application may be found here

Metadata

Release files for revpbuf 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for revpbuf 0.1.1
File Size Uploaded Provenance Actions
revpbuf-0.1.1.tar.gz 6.3 kB Without provenance Details for revpbuf-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for revpbuf 0.1.1
File Interpreter ABI Platform Actions
revpbuf-0.1.1-py2.py3-none-any.whl Python 3, Python 2 none any Details for revpbuf-0.1.1-py2.py3-none-any.whl

Total release size: 12.5 kB

Release files / revpbuf-0.1.1.tar.gz

Download URL revpbuf-0.1.1.tar.gz
Size 6.3 kB
Tags Source
SHA-256 checksum
How to use checksums
cf2268c65ba7183bd1e56e4edb8a0c9bbaf67d8758e40aa0cf67f112903d1531
BLAKE2b-256 checksum
How to use checksums
8eba447fc7e5d113dc9db500b835b279efb9da8a932c45ee38be76b29408a37a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.8.5

Release files / revpbuf-0.1.1-py2.py3-none-any.whl

Download URL revpbuf-0.1.1-py2.py3-none-any.whl
Size 6.3 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
64e603637cfac93e5de885ba2e6a7e80f54f736c56d1281cd78cb144e0824a22
BLAKE2b-256 checksum
How to use checksums
2b99257ed198635d222ffa3abf42ff25e57b1937e2c24ff48ed9332855b5b84f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.8.5

Security for revpbuf 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page