Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,12 @@ module.exports = {
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@firebase|@react-native(-community)?))',
],
// Packages cross-import each other's built output (e.g. database imports
// `@react-native-firebase/app/dist/module/common/deeps`), which resolves
// through the workspace symlink to `packages/*/dist/**`. Without this,
// Jest instruments both that build artifact and the original `lib/**.ts`
// source it was compiled from, so any shared file with branches gets a
// second, all-zero coverage entry alongside the real one, and codecov's
// patch coverage misreports lines that are actually fully tested.
coveragePathIgnorePatterns: ['/node_modules/', '/dist/'],
};
22 changes: 22 additions & 0 deletions packages/app/__tests__/common.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from '@jest/globals';

import { Base64, getDataUrlParts } from '../lib/common';
import { deepSet } from '../lib/common/deeps';

describe('common utilities', () => {
describe('getDataUrlParts', () => {
Expand Down Expand Up @@ -42,4 +43,25 @@ describe('common utilities', () => {
},
);
});

describe('deepSet', () => {
it('rejects paths that mutate the target prototype', () => {
const target = {};

expect(deepSet(target, '__proto__.polluted', true)).toBe(false);
expect((target as Record<string, unknown>).polluted).toBeUndefined();
});

it('rejects paths that mutate Object.prototype', () => {
expect(deepSet({}, 'constructor.prototype.polluted', true, false)).toBe(false);
expect(({} as Record<string, unknown>).polluted).toBeUndefined();
});

it('still assigns values along an ordinary nested path', () => {
const target: Record<string, unknown> = {};

expect(deepSet(target, 'a.b', 5)).toBe(true);
expect(target).toEqual({ a: { b: 5 } });
});
});
});
3 changes: 3 additions & 0 deletions packages/app/lib/common/deeps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ export function deepSet(
return false;
}
const keys = path.split(joiner);
if (keys.some(key => ['__proto__', 'prototype', 'constructor'].includes(key))) {
return false;
}

let i = 0;
let _object: unknown = object;
Expand Down
Loading