fix(zosfiles): handle malformed chtag list response with safe default - #2889
AdeshDeshmukh wants to merge 2 commits into
Conversation
|
Please update the PR to use the full, unabridged PR checklist. Thanks |
isFileTagBinOrAscii and applyTaggedEncoding crashed with unhandled SyntaxError/TypeError on non-JSON, null, empty, or misshapen stdout payloads. Add shared parseChtagStdout helper with null-guard, try/catch, and shape validation so callers fall back to the safe default (false / options unmutated), matching the existing no-stdout behavior. Add 14 unit cases across the crash matrix. Signed-off-by: Adesh Deshmukh <adeshkd123@gmail.com>
Signed-off-by: Adesh Deshmukh <adeshkd123@gmail.com>
ea6f10c to
fd9ea7b
Compare
|
Thanks for the pointers..! |
|
Hi @AdeshDeshmukh can you clarify what steps you encountered to reproduce this error? Is this a known issue with the APIs or just some preventative measures? |
I found this reading the download path, not from a live mainframe incident. So I did the next most honest thing.... I wrote 14 unit tests driving the real code path ( putUSSPayload → the chtag list parse in both methods) with malformed bodies, and ran them against the unmodified code first. This is what came back : IMAGE of failing run ... the 13 red ✕ lines + "Tests: 13 failed, 1 passed"
Every one of those is an unhandled throw out of shipped logic — SyntaxError: Unexpected token '<' on HTML bodies, SyntaxError: Unexpected end of JSON input on empty ones, TypeError: Cannot read properties of null on null bodies, and TypeError variants on empty/misshapen stdout. And this isn't some corner helper, either: every zowe zos-files download uss-file without --binary/--encoding walks straight through applyTaggedEncoding, so any proxy returning an error page or any truncated body takes down the whole download. Then the same run after the fix: IMAGE of passing run — "Test Suites: 1 passed, Tests: 46 passed, 46 total"
Same 14 cases, all green, and the other 32 existing tests untouched — valid-tag behavior is byte-identical, since the fallback is just the safe default the code already used for the {} case. Full output above is verbatim from my terminal about ten minutes ago...! The one thing I'll openly label as inferred rather than proven is how often production serves such bodies .... I can't put a number on that. But the defect itself is on record in the first screenshot, and the fix costs nothing on happy paths. Happy to Move in the direction you would like to...! |


What It Does
Fixes #2888 — and honestly, this one bit me while reading through the USS download path, so I wanted to fix it properly.
The problem in plain terms: every time you download a USS file without passing
--binary/--encoding, the CLI quietly asks z/OSMF for the file's tag (chtag list) to decide whether to convert it. The two helpers behind that —Utilities.isFileTagBinOrAscii()andUtilities.applyTaggedEncoding()(packages/zosfiles/src/methods/utilities/Utilities.ts) — assumed the response would always be neat JSON with astdoutarray. If anything else came back (an HTML error page from a proxy, an empty body, a literalnull, an emptystdout: []), the whole download blew up with a rawSyntaxError/TypeErrorinstead of just carrying on with the default behavior.The fix: a small shared
parseChtagStdout()helper that null-guards the response, wrapsJSON.parsein try/catch, and validates the shape (Array.isArray+typeof string). On anything unparseable, callers now fall back to the safe default —isFileTagBinOrAsciireturnsfalse,applyTaggedEncodingleaves yourbinary/encodingoptions untouched — exactly like the existing no-stdout({}) case already did. Valid-tag handling is byte-for-byte unchanged, so no behavior change for happy paths, no API change.How to Test
No mainframe needed — everything is unit-testable with a mocked
putUSSPayload:npx jest packages/zosfiles/__tests__/__unit__/methods/utilities/Utilities.unit.test.ts --coverage false→ 45/45 pass, including 14 new cases covering the full crash matrix (null, empty body, HTML,"null",stdout: [], non-arraystdout, non-string entry) for both methods.npx eslint src/methods/utilities/Utilities.ts(frompackages/zosfiles) → clean.npx tsc --noEmit -p tsconfig.json(frompackages/zosfiles) → clean.putUSSPayloadto resolveBuffer.from('<html>error</html>')and confirmisFileTagBinOrAsciiresolvesfalseinstead of throwing.Review Checklist
I certify that I have:
Additional Comments