Skip to content

getAttributeXPath throws on messages without an excerpt (nuVal 'Too many messages.' fatal) — aborts the whole reporter #46

Description

@wittjeff

Summary

procs/xPath.js getAttributeXPath(html) calls html.match(...) with no guard. The Nu Html Checker (used by the nuVal tool) can return messages that have no extract field, so nuVal passes undefined in, undefined.match(...) throws, and — because the call sits outside nuVal's try/catch — the whole reporter aborts. The act comes back bare (no result/data), reported downstream as "no result", and all of the page's real findings are discarded.

Trigger

The Nu validator caps output at 1000 messages. When a page has more than 1000 validity issues, it appends a fatal meta-message with no extract:

{ "type": "error", "subType": "fatal", "message": "Too many messages." }

tests/nuVal.js then does, for every message:

const xPath = getAttributeXPath(message.extract);   // message.extract === undefined

and getAttributeXPath:

exports.getAttributeXPath = html => {
  const match = html.match(/ data-xpath="([^" ]+)"/);   // undefined.match() -> TypeError
  return match ? match[1] : '/html';
};

This is masked when nuVal uses the public W3C service, because W3C returns HTTP 502 on bodies larger than ~80 kB (so it never returns messages for the kind of large page that would exceed the 1000-message cap). Pointing nuVal at a self-hosted validator via TESTARO_NU_URL — which handles large pages — surfaces the bug: the validator succeeds, returns 1001 messages, and nuVal throws on the last one.

Reproduction

Validate any page with >1000 Nu validity errors through a self-hosted validator (ghcr.io/validator/validator) with TESTARO_NU_URL set. The nuVal act returns bare; the log shows TypeError: Cannot read properties of undefined (reading 'match') from getAttributeXPath.

Verified against a real 1001-message response: curate() returns all 1001 messages fine; the per-message loop in nuVal.js throws on the extract-less "Too many messages." entry.

Suggested fix

Guard the helper (it's also called by tests/ibm.js on element snippets, so this hardens that path too):

exports.getAttributeXPath = html => {
  const match = (html || '').match(/ data-xpath="([^" ]+)"/);
  return match ? match[1] : '/html';
};

Optionally, nuVal.js could also skip messages without an extract when building standard instances, so a fatal meta-message like "Too many messages." isn't emitted as a finding at /html.

Impact

Any nuVal scan of a large, very-invalid page through a self-hosted validator fails completely (0 of 1000 findings reported) instead of returning the capped results — and the failure is opaque ("no result"). We're patching getAttributeXPath downstream; the fix belongs upstream.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions