Skip to content

Commit 67be597

Browse files
committed
feat: wrap inflation errors
`pako` has a tendency to throw obscure error strings e.g. "too many length or distance symbols", which can make gracefully handling bad input difficult when an error is thrown from `parseLoginRequest`. This wraps the inflation step to allow throwing a dedicated error with a static message for inflation issues, while still making the original error available.
1 parent 49295a2 commit 67be597

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

src/flow.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { inflateString, base64Decode } from './utility';
1+
import { inflateString, base64Decode, WrappedError } from './utility';
22
import { verifyTime } from './validator';
33
import libsaml from './libsaml';
44
import {
@@ -67,7 +67,13 @@ async function redirectFlow(options): Promise<FlowResult> {
6767
return Promise.reject('ERR_REDIRECT_FLOW_BAD_ARGS');
6868
}
6969

70-
const xmlString = inflateString(decodeURIComponent(content));
70+
let xmlString: string
71+
72+
try {
73+
xmlString = inflateString(decodeURIComponent(content));
74+
} catch (cause) {
75+
throw new WrappedError('ERR_FAILED_INFLATION', { cause })
76+
}
7177

7278
// validate the xml
7379
try {

src/utility.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ import { inflate, deflate } from 'pako';
88

99
const BASE64_STR = 'base64';
1010

11+
/**
12+
* An Error class with a "cause".
13+
*
14+
* This can be replaced by the native option, once the minimum supported version is >=16.9.0.
15+
* https://nodejs.org/docs/latest-v16.x/api/errors.html#errorcause
16+
*/
17+
export class WrappedError extends Error {
18+
public cause: any;
19+
20+
constructor(message: string, options: { cause: any }) {
21+
super(message);
22+
this.cause = options.cause;
23+
}
24+
}
25+
1126
/**
1227
* @desc Mimic lodash.zipObject
1328
* @param arr1 {string[]}

test/flow.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,3 +1382,11 @@ test.serial('should not throw ERR_SUBJECT_UNCONFIRMED for the expired SAML respo
13821382
}
13831383

13841384
});
1385+
1386+
test('should throw ERR_FAILED_INFLATION when pako is unable to inflate a redirect login request', async t => {
1387+
const query = { SAMLRequest: 'foo', Signature: 'bar', SigAlg: 'baz' };
1388+
const error = await t.throwsAsync<any>(idp.parseLoginRequest(sp, 'redirect', { query }));
1389+
1390+
t.is(error.message, 'ERR_FAILED_INFLATION');
1391+
t.is(error.cause, 'invalid block type'); // pako throws strings instead of Error instances for bad input
1392+
});

0 commit comments

Comments
 (0)