Skip to content

Commit

Permalink
Escape pasted text in compose area
Browse files Browse the repository at this point in the history
Sanitizing text would cause some non-HTML text to disappear (see #86).
Instead, we escape HTML, so that it looks exactly like pasted.

The applyFilters helper function has been removed, it's unclear what it
does. Being explicit is better in this case.

Pasting emoji tags still works, because <img> tags are converted to
their alt-text, which is in turn converted back to an <img> tag by the
emojify filter.
  • Loading branch information
threema-danilo committed Feb 27, 2017
1 parent 6413c71 commit 3ef1e7e
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 19 deletions.
29 changes: 12 additions & 17 deletions src/directives/compose_area.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ export default [
'$translate',
'$mdDialog',
'$filter',
'$sanitize',
'$log',
function(browserService: threema.BrowserService,
stringService: threema.StringService,
$window, $timeout: ng.ITimeoutService,
$translate: ng.translate.ITranslateService,
$mdDialog: ng.material.IDialogService,
$filter: ng.IFilterService,
$sanitize: ng.sanitize.ISanitizeService,
$log: ng.ILogService) {
return {
restrict: 'EA',
Expand Down Expand Up @@ -277,12 +275,6 @@ export default [
});
}

function applyFilters(text: string): string {
const emojify = $filter('emojify') as (a: string, b?: boolean) => string;
const parseNewLine = $filter('nlToBr') as (a: string, b?: boolean) => string;
return parseNewLine(emojify(text, true), true);
}

// Handle pasting
function onPaste(ev: ClipboardEvent) {
ev.preventDefault();
Expand Down Expand Up @@ -346,17 +338,20 @@ export default [
} else if (textIdx !== null) {
const text = ev.clipboardData.getData('text/plain');

// Apply filters (emojify, convert newline, etc)
const formatted = applyFilters(text);

// Replace HTML formatting with ASCII counterparts
// Look up some filter functions
const htmlToAsciiMarkup = $filter('htmlToAsciiMarkup') as (a: string) => string;
const escapeHtml = $filter('escapeHtml') as (a: string) => string;
const emojify = $filter('emojify') as (a: string, b?: boolean) => string;
const nlToBr = $filter('nlToBr') as (a: string, b?: boolean) => string;

// Escape HTML markup
const escaped = escapeHtml(htmlToAsciiMarkup(text));

// Sanitize
const sanitized = $sanitize(htmlToAsciiMarkup(formatted));
// Apply filters (emojify, convert newline, etc)
const formatted = nlToBr(emojify(escaped, true), true);

// Insert HTML
document.execCommand('insertHTML', false, sanitized);
// Insert resulting HTML
document.execCommand('insertHTML', false, formatted);

cleanupComposeContent();
updateView();
Expand Down Expand Up @@ -419,7 +414,7 @@ export default [
function onEmojiChosen(ev: MouseEvent): void {
ev.stopPropagation();
const emoji = this.textContent; // Unicode character
const formatted = applyFilters(emoji);
const formatted = ($filter('emojify') as any)(emoji, true);

// Firefox inserts a <br> after editing content editable fields.
// Remove the last <br> to fix this.
Expand Down
3 changes: 1 addition & 2 deletions src/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ angular.module('3ema.filters', [])
if (text === undefined || text === null) {
text = '';
}
const escaped = text.replace(/[&<>"']/g, (m) => map[m]);
return escaped;
return text.replace(/[&<>"']/g, (m) => map[m]);
};
})

Expand Down

0 comments on commit 3ef1e7e

Please sign in to comment.