Skip to content

Commit

Permalink
Don't linkify when certain unicode formatting characters are present
Browse files Browse the repository at this point in the history
  • Loading branch information
scottnonnenberg-signal committed Mar 29, 2022
1 parent e626063 commit 006de5b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
6 changes: 5 additions & 1 deletion ts/components/conversation/Linkify.tsx
Expand Up @@ -6,7 +6,7 @@ import React from 'react';
import LinkifyIt from 'linkify-it';

import type { RenderTextCallbackType } from '../../types/Util';
import { isLinkSneaky } from '../../types/LinkPreview';
import { isLinkSneaky, shouldLinkifyMessage } from '../../types/LinkPreview';
import { splitByEmoji } from '../../util/emoji';
import { missingCaseError } from '../../util/missingCaseError';

Expand Down Expand Up @@ -333,6 +333,10 @@ export class Linkify extends React.Component<Props> {
| Array<JSX.Element | string | null> {
const { text, renderNonLink } = this.props;

if (!shouldLinkifyMessage(text)) {
return text;
}

// We have to do this, because renderNonLink is not required in our Props object,
// but it is always provided via defaultProps.
if (!renderNonLink) {
Expand Down
21 changes: 21 additions & 0 deletions ts/test-node/types/LinkPreview_test.ts
Expand Up @@ -5,6 +5,7 @@ import { assert } from 'chai';

import {
findLinks,
shouldLinkifyMessage,
shouldPreviewHref,
isLinkSneaky,
} from '../../types/LinkPreview';
Expand Down Expand Up @@ -44,6 +45,26 @@ describe('Link previews', () => {
});
});

describe('#shouldLinkifyMessage;', () => {
it('returns false for strings with directional override characters', () => {
assert.isFalse(shouldLinkifyMessage('\u202c'));
assert.isFalse(shouldLinkifyMessage('\u202d'));
assert.isFalse(shouldLinkifyMessage('\u202e'));
});

it('returns false for strings with unicode drawing characters', () => {
assert.isFalse(shouldLinkifyMessage('\u2500'));
assert.isFalse(shouldLinkifyMessage('\u2588'));
assert.isFalse(shouldLinkifyMessage('\u25FF'));
});

it('returns true other strings', () => {
assert.isTrue(shouldLinkifyMessage(null));
assert.isTrue(shouldLinkifyMessage(undefined));
assert.isTrue(shouldLinkifyMessage('Random other string aqu%C3%AD'));
});
});

describe('#findLinks', () => {
it('returns all links if no caretLocation is provided', () => {
const text =
Expand Down
24 changes: 24 additions & 0 deletions ts/types/LinkPreview.ts
Expand Up @@ -38,6 +38,26 @@ export function shouldPreviewHref(href: string): boolean {
);
}

const DIRECTIONAL_OVERRIDES = /[\u202c\u202d\u202e]/;
const UNICODE_DRAWING = /[\u2500-\u25FF]/;

export function shouldLinkifyMessage(
message: string | null | undefined
): boolean {
if (!message) {
return true;
}

if (DIRECTIONAL_OVERRIDES.test(message)) {
return false;
}
if (UNICODE_DRAWING.test(message)) {
return false;
}

return true;
}

export function isStickerPack(link = ''): boolean {
return link.startsWith('https://signal.art/addstickers/');
}
Expand All @@ -47,6 +67,10 @@ export function isGroupLink(link = ''): boolean {
}

export function findLinks(text: string, caretLocation?: number): Array<string> {
if (!shouldLinkifyMessage(text)) {
return [];
}

const haveCaretLocation = isNumber(caretLocation);
const textLength = text ? text.length : 0;

Expand Down

0 comments on commit 006de5b

Please sign in to comment.