Skip to content

string_iter() doesn't handle unix paths — inconsistent with _from_string() #112

Description

@sumanjeet0012

string_iter() in transforms.py doesn't have special handling for unix paths (which consume the rest of the string as a single value). This is inconsistent with _from_string() in multiaddr.py which does handle unix paths correctly.

Problem

In multiaddr/transforms.py:

def string_iter(string: str):
    parts = string.strip("/").split("/")
    i = 0
    while i < len(parts):
        proto_name = parts[i]
        proto = protocol_with_name(proto_name)
        codec = codec_by_name(proto.codec)
        value = None
        if proto.codec is not None:
            value = parts[i + 1]    # ← Only takes ONE part as value
            i += 1
        yield proto, codec, value
        i += 1

For unix paths, the value can contain / characters:

# _from_string() handles this correctly:
ma = Multiaddr("/unix/var/run/docker.sock")
# → correctly parses "var/run/docker.sock" as the path value

# But string_iter() splits on every "/":
list(string_iter("/unix/var/run/docker.sock"))
# → yields ("unix", codec, "var"), then fails on "run" as unknown protocol

_from_string() has explicit unix handling:

if part in ("unix",):
    protocol_path_value = parts[idx + 1]
    remaining_parts = [p for p in parts_list[idx + 2:] if p]
    if remaining_parts:
        protocol_path_value = protocol_path_value + "/" + "/".join(remaining_parts)
    # ...

Proposed Solution

Add unix path handling to string_iter():

def string_iter(string: str):
    parts = string.strip("/").split("/")
    i = 0
    while i < len(parts):
        proto_name = parts[i]
        proto = protocol_with_name(proto_name)
        codec = codec_by_name(proto.codec)
        value = None

        if proto.codec is not None:
            if proto.name == "unix":
                # Unix paths consume the rest of the string
                value = "/".join(parts[i + 1:])
                i = len(parts)  # Consume all remaining
            else:
                if i + 1 >= len(parts):
                    raise exceptions.StringParseError(
                        f"missing value for protocol: {proto_name}", string
                    )
                value = parts[i + 1]
                i += 1
        yield proto, codec, value
        i += 1

Also handle any other path protocols (check codec.IS_PATH).

Related

  • File: multiaddr/transforms.py
  • Consistent implementation: multiaddr/multiaddr.py _from_string()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions