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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions