Skip to content

Commit

Permalink
Fix Object with 'length' key bug
Browse files Browse the repository at this point in the history
This commit fixes a bug where SDK fails to serialize JavaScript Objects
if they contain key 'length' with number value.

The reason for this bug seems to be in lodash `_.reduce` function. See
lodash/lodash#5870

The solution is to use Object.entries + reduce instead of lodash reduce.
  • Loading branch information
rap1ds committed May 27, 2024
1 parent e890e2c commit e30d983
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 23 deletions.
14 changes: 6 additions & 8 deletions src/interceptors/multipart_request.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _ from 'lodash';
import { entries } from '../utils';

/**
Takes `params` from `ctx` and converts to `FormData`
Expand All @@ -17,14 +18,11 @@ export default class MultipartRequest {
);
}

const formDataObj = _.reduce(
params,
(fd, val, key) => {
fd.append(key, val);
return fd;
},
new FormData()
);
const formDataObj = entries(v).reduce((fd, entry) => {
const [val, key] = entry;
fd.append(key, val);
return fd;
}, new FormData());
/* eslint-enable no-undef */

return { params: formDataObj, ...ctx };
Expand Down
14 changes: 6 additions & 8 deletions src/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import transit from 'transit-js';
import _ from 'lodash';
import { UUID, LatLng, Money, BigDecimal, toType } from './types';
import { entries } from './utils';

/**
Composes two readers (sdk type and app type) so that:
Expand Down Expand Up @@ -168,14 +169,11 @@ const MapHandler = [
transit.makeWriteHandler({
tag: () => 'map',
rep: v =>
_.reduce(
v,
(map, val, key) => {
map.set(transit.keyword(key), val);
return map;
},
transit.map()
),
entries(v).reduce((map, entry) => {
const [key, val] = entry;
map.set(transit.keyword(key), val);
return map;
}, transit.map()),
}),
];

Expand Down
18 changes: 18 additions & 0 deletions src/serializer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ describe('serializer', () => {
expect(r.read(w.write(testData))).toEqual(testData);
});

it('reads and writes Object with key length', () => {
// See: https://github.com/lodash/lodash/issues/5870
const testData = {
a: 1,
b: 2,
c: [3, 4, 5],
d: {
e: true,
},
length: 10,
};

const r = reader();
const w = writer();

expect(r.read(w.write(testData))).toEqual(testData);
});

it('reads and writes transit JSON verbose', () => {
const testData = {
a: 1,
Expand Down
21 changes: 15 additions & 6 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import _ from 'lodash';

/**
Null-safe version of Object.entries
*/
export const entries = obj => {
if (obj == null) {
return [];
}
return Object.entries(obj);
};

/**
Take URL and remove the trailing slashes.
Expand All @@ -17,14 +27,13 @@ export const fnPath = path =>
_.without(path.split('/'), '').map(part => part.replace(/_\w/g, m => m[1].toUpperCase()));

export const formData = params =>
_.reduce(
params,
(pairs, v, k) => {
entries(params)
.reduce((pairs, entry) => {
const [k, v] = entry;
pairs.push(`${encodeURIComponent(k)}=${encodeURIComponent(v)}`);
return pairs;
},
[]
).join('&');
}, [])
.join('&');

/**
Serialize a single attribute in an object query parameter.
Expand Down
13 changes: 12 additions & 1 deletion src/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { fnPath, trimEndSlash, formData, objectQueryString, canonicalAssetPaths } from './utils';
import {
fnPath,
trimEndSlash,
formData,
objectQueryString,
canonicalAssetPaths,
} from './utils';

describe('utils', () => {
describe('pathToMethodName', () => {
Expand Down Expand Up @@ -33,6 +39,11 @@ describe('utils', () => {
formData({ username: '[email protected]', password: '}4$3.872487=3&&]/6?.' })
).toEqual('username=joe.dunphy%40example.com&password=%7D4%243.872487%3D3%26%26%5D%2F6%3F.');
});

it('encodes Object with key length', () => {
// See: https://github.com/lodash/lodash/issues/5870
expect(formData({ length: 10 })).toEqual('length=10');
});
});

describe('objectQueryString', () => {
Expand Down

0 comments on commit e30d983

Please sign in to comment.