Skip to content

Commit

Permalink
fix: only replace trailing slash on decode (#11899)
Browse files Browse the repository at this point in the history
**Motivation**

I first noticed this in `@react-navigation/core@6.4.14`. I think it
happened in
#11869

When you decode a path param that has an encoded `/` it removes the
encoded param and leaves the trailing param in state.

**Test plan**
Create a route that have a path param with a`%2F` in it, verify that it
comes out correctly decoded
  • Loading branch information
cranberyxl authored and satya164 committed Mar 18, 2024
1 parent 4edbb07 commit 31bb8a1
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
76 changes: 76 additions & 0 deletions packages/core/src/__tests__/getStateFromPath.test.tsx
Expand Up @@ -48,6 +48,82 @@ it('converts path string to initial state', () => {
);
});

it('decodes encoded params in path', () => {
const path = '/foo/bar/bar_%23_foo';
const config = {
screens: {
Foo: {
path: 'foo',
screens: {
Bar: {
path: '/bar/:id',
},
},
},
},
};

const state = {
routes: [
{
name: 'Foo',
state: {
routes: [
{
name: 'Bar',
params: { id: 'bar_#_foo' },
path,
},
],
},
},
],
};

expect(getStateFromPath<object>(path, config)).toEqual(state);
expect(
getPathFromState<object>(getStateFromPath<object>(path, config)!, config)
).toEqual(path);
});

it('decodes encoded params in path that have encoded /', () => {
const path = '/foo/bar/bar_%2F_foo';
const config = {
screens: {
Foo: {
path: 'foo',
screens: {
Bar: {
path: '/bar/:id',
},
},
},
},
};

const state = {
routes: [
{
name: 'Foo',
state: {
routes: [
{
name: 'Bar',
params: { id: 'bar_/_foo' },
path,
},
],
},
},
],
};

expect(getStateFromPath<object>(path, config)).toEqual(state);
expect(
getPathFromState<object>(getStateFromPath<object>(path, config)!, config)
).toEqual(path);
});

it('converts path string to initial state with config', () => {
const path = '/foo/bar/sweet/apple/baz/jane?count=10&answer=42&valid=true';
const config = {
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/getStateFromPath.tsx
Expand Up @@ -302,11 +302,13 @@ const matchAgainstConfigs = (remaining: string, configs: RouteConfig[]) => {
const decodedParamSegment = decodeURIComponent(
// The param segments appear every second item starting from 2 in the regex match result
match![(acc.pos + 1) * 2]
// Remove trailing slash
.replace(/\/$/, '')
);

Object.assign(acc.matchedParams, {
[p]: Object.assign(acc.matchedParams[p] || {}, {
[index]: decodedParamSegment.replace(/\//, ''),
[index]: decodedParamSegment,
}),
});

Expand Down

0 comments on commit 31bb8a1

Please sign in to comment.