Skip to content

Since #1152, a plain-ASCII requirements.txt whose coding line names an unmodelled codec (iso-8859-15, cp1250, gbk…) is read as absent: scan finds nothing (exit 0), and vex / rollback can't see an existing hosted pin #1212

Description

[agent] Found by the scheduled pip / requirements.txt bug-hunt routine (ledger #309).

Summary

#1152 (fix for #1119 / #1120) sends every requirements reader through utils::requirements::decode. When the file has a PEP 263 coding line, decode maps the codec name through coding_line_codec, which only knows UTF-8, ASCII, Latin-1 and cp1252. For any other name it returns None, so the whole file is treated as unreadable. That includes common ASCII-compatible codecs such as iso-8859-15 / latin-9, cp1250, mac-roman and gbk.

This applies even when the file is pure ASCII, which is the usual case when a coding header was copied from a template. In that case every ASCII-compatible codec decodes the bytes the same way, and pip reads the file fine. v4.0.0 and the parent commit 03b9418 read these files as UTF-8 and handled them correctly.

Impact (main 793edd4)

  • scan / lock-only discovery finds no packages: scannedPackages: 0, status: success, exit 0, and no warning. A fresh checkout looks clean while pip installs the vulnerable release.
  • scan --mode hosted rewrites nothing and exits 0 with no warning.
  • On a project that's already hosted (wired by v4.0.0 or an earlier main), vex exits 2 with "cannot read requirements.txt: not text pip's decoding rules can read". rollback exits 1 with manifest_not_found. The hosted pin can't be attested or unwound until the user deletes the coding line.

Repro

mkdir proj && cd proj
printf '# -*- coding: iso-8859-15 -*-\nsix==1.16.0\n' > requirements.txt   # pure ASCII
python3 -m venv /tmp/empty           # empty VIRTUAL_ENV keeps it lock-only
pip install --dry-run -r requirements.txt     # pip 20.3.4 and 26.2.1: resolves six==1.16.0
VIRTUAL_ENV=/tmp/empty socket-patch scan --json --dry-run
#   main 793edd4: batch request has no components, scannedPackages 0, exit 0
#   03b9418 / v4.0.0: batch asks for pkg:pypi/six@1.16.0, scannedPackages 1

# already-hosted variant (requirements.txt wired by 03b9418 / v4.0.0):
#   # -*- coding: iso-8859-15 -*-
#   six @ https://patch.socket.dev/patch/pypi/six/1.16.0/…/six-1.16.0-py2.py3-none-any.whl#sha256=…
socket-patch vex --product pkg:pypi/app@1.0.0   # main: exit 2 ("cannot read requirements.txt …"); 03b9418: not_affected, exit 0
socket-patch rollback --yes --json              # main: exit 1, manifest_not_found; 03b9418: exit 0, file restored

The same result came back for cp1250, latin-9, mac-roman and gbk. # -*- coding: utf-8 -*- still works. All runs used a local mock patch API with a real patched wheel, and each repro ran at least twice.

Expected vs actual

Matrix (Linux)

Build pip lock-only scan hosted scan vex on hosted file rollback on hosted file
v4.0.0 26.2.1 finds six n/a n/a n/a
03b9418 (parent of #1152) 20.3.4 / 26.2.1 finds six rewrites not_affected, exit 0 exit 0, restored
main 793edd4 20.3.4 / 26.2.1 0 packages, exit 0 no-op, exit 0 exit 2 exit 1 manifest_not_found

macOS / Windows weren't probed. The code path is OS-independent.

First bad commit: 793edd4 (#1152).

Suspect code

  • crates/socket-patch-core/src/utils/requirements.rs:57: coding_line_codec(&name)? returns None for any codec the reader doesn't model, even when the bytes are ASCII (or valid UTF-8) and every ASCII-compatible codec would decode them identically.
  • crates/socket-patch-core/src/utils/requirements.rs:109: coding_line_codec covers only UTF-8 / ASCII / Latin-1 / cp1252.

A possible direction: when the codec isn't modelled and the bytes are pure ASCII, decode them as ASCII. Or fail loudly with a warning rather than reading the file as absent. I haven't filed a fix.

Activity

  1. added
    bugSomething isn't working
    bughuntFound by a scheduled package-manager bug-hunt agent
    pm:pippip / requirements.txt
    on Oct 9, 2026
  2. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Triage: priority:p1 (PyPI/pip). Confirmed on main f3c6313: utils::requirements::decode returns None from coding_line_codec(&name)? (crates/socket-patch-core/src/utils/requirements.rs:57) for any codec outside UTF-8/ASCII/Latin-1/cp1252, even for pure-ASCII bytes. No open PR or later commit addresses it; not a duplicate of #1119/#1120 (those were fixed by #1152, which introduced this).


    Generated by Claude Code

  3. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Claiming this issue (shared root cause: coding_line_codec returns None for unmodelled PEP 263 codecs, so decode reads ASCII-compatible files as undecodable). Branch: agent/fix-requirements-unmodelled-coding-line. Claim-ID: 2026-10-09T03:20:43Z-87949d


    Generated by Claude Code

  4. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Draft PR: #1218


    Generated by Claude Code

  5. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Verified fixed on main e03a666 (includes #1218). On Linux, a lock-only scan of an ASCII requirements file with a # -*- coding: X -*- header now requests pkg:pypi/six@1.16.0 for X = iso-8859-15, cp1250, gbk and mac-roman. That holds both as the root requirements.txt and as a -r dev.txt include (8/8 cells, exit 0).


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedbugSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentpm:pippip / requirements.txtpriority:p1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions