Skip to content

feat(libc): implement __inet_aton - #1848

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
LeandroLP23:feat/libc-inet-aton
Oct 9, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
LeandroLP23:feat/libc-inet-aton

Conversation

@LeandroLP23

Copy link
Copy Markdown
Contributor

What

PICO-8 for PS5 (PPSA99808 v0.1.2, RafaelNGP/pico8-ps5, GPL-3.0) stops at start-up on main:

FAIL: unresolved ELF import a7ToDPsIQrc from libSceLibcInternal.prx

a7ToDPsIQrc is __inet_aton (tools/nid_names.py). It is the only title in @SleglJan's run of the catalog (#1578) that stops there.

The parser follows FreeBSD's inet_aton (lib/libc/inet/inet_addr.c):

  • one to four parts, each in decimal, octal (leading 0) or hex (0x);
  • the last part fills the remaining bytes (a.b → a.0.0.b with b up to 24 bits, a.b.c with c up to 16 bits, a single number for all 32 bits);
  • the input ends at a NUL or a whitespace character;
  • it returns 1 and writes the address in network order, or returns 0 and leaves the output untouched;
  • a null address only validates.

Windows has no inet_aton, and glibc's differs in its overflow checks, so the parser is written out instead of calling the host's. It is in StringExtensions.cpp rather than a new file, so it does not collide with the Network.cpp that #1766 (__inet_addr, __inet_ntoa) adds.

Tested

Windows 11, MinGW-w64 GCC 15.2.0, Release, main 364a56b:

  • PICO-8 gets past this import and stops at the next one, +2thxYZ4syk from libkernel.prx (environ).
  • guest_strings, 3/3, also after rebasing onto main 94b1eec. New checks:
    • dotted forms: 192.0.2.42, 10.1.2, 127.1, 3232235777;
    • hex and octal parts;
    • input ended by trailing whitespace;
    • a null output;
    • 13 invalid inputs, which return 0 and leave the output untouched: an empty string, a leading space, five parts, parts out of range, 08, 1..2, letters, trailing garbage, a bare 0x, a trailing dot, a sign.
  • tools/check_conventions.py passes.

Linux and Windows: fork CI https://github.com/LeandroLP23/AnyPS5/actions/runs/37846914473, all jobs pass (on the same change based on 364a56b6).

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes (Claude Code)

PICO-8 for PS5 (PPSA99808) stops at start-up on the unresolved import
a7ToDPsIQrc from libSceLibcInternal. The parser follows FreeBSD's inet_aton
(lib/libc/inet/inet_addr.c): one to four parts in decimal, octal or hex, the
last part filling the remaining bytes, input ending at a NUL or whitespace,
and a null address only validating.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Progress report (94b1eec → 7449e51)

➖ System libraries: 84.76% (+0.0%, +1 implemented functions)

✅ 1 implemented
Library Name
libc __inet_aton_nid_postfix

@github-actions github-actions Bot added the libc label Oct 8, 2026
@babyhuey babyhuey mentioned this pull request Oct 9, 2026
9 tasks done
@CouchRiv CouchRiv mentioned this pull request Oct 9, 2026
9 tasks done

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one-part limit is too large: limits[0] is UINT64_MAX, but the documented a form occupies 32 bits. As written, 4294967296 is accepted and truncated to 0.0.0.0. Also, the digit accumulation wraps in uint64_t: 18446744073709551617 wraps to 1 and is accepted as 0.0.0.1. Please cap the one-part form at 0xffffffff and reject overflow during multiply/add (or otherwise parse with checked bounds). Add boundary tests for 4294967295 (valid), 4294967296 (invalid), and a value that exceeds uint64_t; the same checked accumulation should cover hex and octal.

@CouchRiv

CouchRiv commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

On the one-part limit: FreeBSD's inet_aton accepts values above 32 bits there. val is a u_long (L102), accumulated without an overflow check (L132), the one-part case has no range check (L174), and the result is truncated by htonl(val) (L197). So on FreeBSD amd64, 4294967296 gives 0.0.0.0 and 18446744073709551617 gives 0.0.0.1, as this PR does.

I compared FreeBSD's parser (that file, built unchanged on Linux x86-64) against a parser written to the same rules for 24,806 inputs: part-boundary and 32/64-bit wrap values, every trailing byte, all whitespace characters, malformed prefixes. There were no differences. glibc rejects 4294967297, so capping at 0xffffffff would follow glibc rather than the PS5's FreeBSD libc.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction to my earlier review: I verified the pinned FreeBSD inet_aton source you linked. On amd64, the one-part form intentionally has no 32-bit range check, and accumulation in u_long wraps before htonl; the examples you gave match that implementation. I retract both the 32-bit cap request and the request to reject unsigned accumulation wrap. My earlier requested boundary tests would encode the wrong semantics. Sorry for the incorrect review. I cannot dismiss my prior review with this account; please treat this correction as withdrawing it.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after verifying the FreeBSD source semantics; my prior change request was incorrect and is withdrawn.

@MarcZX10

MarcZX10 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

PR #2231 is now the canonical, more complete IPv4-helper change. It includes this implementation along with the other parsing/formatting helpers, preserves the original author commits in its history, and adds cross-function round-trip coverage. The exact head has a local Linux full-build result with the documented GCC 12 SaveData workaround, and I requested the upstream Build. Please close this overlapping PR as superseded once the current-head Build on #2231 is reviewed.

@LeandroLP23

Copy link
Copy Markdown
Contributor Author

Thanks for preserving the commit. I'd rather keep #1848 open until a maintainer decides: today #1839 was closed for putting three exports in one PR, and library functions go in when a title stops on them on main. #1848 is one export with PICO-8's stop on main (and your approval), while __inet_ntoa has no title stop shown yet. If #2231 is preferred, I'll close #1848 then.

@MarcZX10

MarcZX10 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

That concern is fair. For the combined IPv4-helper topic, I think #2231 is the better canonical PR: it preserves your __inet_aton implementation and attribution, adds __inet_addr and __inet_ntoa, and covers cross-function round trips. The title-run report is explicitly documented as external evidence, not a test with #2231. Its exact-head upstream Build is still pending, and I agree the maintainers should decide whether this cohesive set belongs in one PR under the one-topic rule. I will follow that decision; please keep #1848 open until then.

@A-Akhil A-Akhil mentioned this pull request Oct 9, 2026
9 tasks done
@MarcZX10

MarcZX10 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Update after rebase: #2231 is now on current main (f8c2f072) at 863ff49f; its Linux guest_strings test passes 1/1 and Conventions passes. The Windows results in its description are from the pre-rebase head 6923a54e, not this head, and the exact-head upstream Build is still pending.

I still consider #2231 the better canonical target for the IPv4 helper family because it preserves and combines the three implementations and adds cross-function tests. The overlapping PRs remain open until maintainers decide whether this cohesive family should land together; I am not treating the old Windows batch as current-head validation.

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked against FreeBSD lib/libc/inet/inet_addr.c (part limits, bases, whitespace terminator, untouched output on failure, no 32-bit cap on the one-part form, as in FreeBSD amd64), built and ran guest_strings (the new checks fail to link without the change); Linux/Windows/conventions CI green. Merging.

@adriadam10
adriadam10 merged commit aad16d0 into boykopovar:main Oct 9, 2026
6 checks passed
@LeandroLP23
LeandroLP23 deleted the feat/libc-inet-aton branch October 10, 2026 09:18
@Amirtheshwaran Amirtheshwaran mentioned this pull request Oct 10, 2026
6 tasks done
@AchrafReyani AchrafReyani mentioned this pull request Oct 11, 2026
9 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants