fix(process): keep ports before a chunk-final period

PTY chunks are normalized independently. A period that ends a chunk may
begin a decimal continued in the next chunk ("port: 80." then "5"), so
leave such a port unnormalized instead of masking the decimal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822andClaude Opus 5.5 committed 2026-10-09 14:19:37 +00:00
1 parent db98a51dd1
commit 184ed970b9
3 files changed
+13 -3

No files matched your search

+2 -1
View File
@@ -114,7 +114,8 @@ Port normalization recognizes explicit `port`, `tcp_port`, `udp_port`, and
`listen` fields, URL authorities, IP endpoints, and `localhost` endpoints, with
ports from 0 through 65535. A port may end a sentence, as in `port: 8080.`;
a period followed by a letter or digit continues a decimal, version, or host
name instead. It preserves ordinary counters, dimensions, file line numbers,
name instead. Each PTY chunk is normalized on its own, so a port whose period
ends the chunk is left unchanged because its continuation is not yet known. It preserves ordinary counters, dimensions, file line numbers,
and ambiguous bare host labels. Use explicit literal `patterns`
for a different application-specific spelling. Set `ports: false` to preserve
all endpoint numbers in comparison text. Captures commit the port-normalization
@@ -118,6 +118,13 @@ it("normalizes ports that end a sentence but not decimal or host continuations",
);
});
it("keeps a port before a chunk-final period, whose continuation is unknown", () => {
for (const chunk of ["port: 80.", "http://localhost:8080.", "[::1]:3000."])
expect(
normalizeProcessText(chunk, scenario({}), "/temporary", rootPid),
).toBe(chunk);
});
it("normalizes representative process identities and preserves null, zero, and unrelated numbers", () => {
const before = JSON.stringify(samples);
const normalized = normalizeProcessSamples(samples, scenario({}), rootPid);
+4 -2
View File
@@ -43,9 +43,11 @@ export const normalizeProcessText = (
// A port may end a sentence, but a period followed by a word character
// continues a decimal, version, or host name and is not a port boundary.
// PTY chunks are normalized independently, so a period that ends the chunk
// stays unnormalized: its continuation may arrive in the next chunk.
const normalizePortTokens = (value: string): string => {
const endpointNormalized = value.replaceAll(
/(\b[a-z][a-z0-9+.-]*:\/\/[^\s/?#"'<>]+|\blocalhost|\b(?:\d{1,3}\.){3}\d{1,3}|\[[\da-f:.%]+\]):(\d{1,5})(?![\w@:]|\.\w)/giu,
/(\b[a-z][a-z0-9+.-]*:\/\/[^\s/?#"'<>]+|\blocalhost|\b(?:\d{1,3}\.){3}\d{1,3}|\[[\da-f:.%]+\]):(\d{1,5})(?![\w@:]|\.(?:\w|$))/giu,
(match: string, endpoint: string, port: string) => {
if (Number(port) > 65_535) return match;
const isEndpoint = endpoint.includes("://")
@@ -56,7 +58,7 @@ const normalizePortTokens = (value: string): string => {
},
);
return endpointNormalized.replaceAll(
/(\b(?:port|tcp_port|udp_port|listen)\b["']?\s*[:=]\s*)(\d{1,5})(?!\w|\.\w)/giu,
/(\b(?:port|tcp_port|udp_port|listen)\b["']?\s*[:=]\s*)(\d{1,5})(?!\w|\.(?:\w|$))/giu,
(match: string, prefix: string, port: string) =>
Number(port) <= 65_535 ? `${prefix}<port>` : match,
);