Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix document name XSS
  • Loading branch information
morethanwords committed Jul 20, 2021
1 parent 6517ee4 commit 11d2fe0
Show file tree
Hide file tree
Showing 24 changed files with 275 additions and 130 deletions.
3 changes: 1 addition & 2 deletions src/components/appSearchSuper..ts
Expand Up @@ -868,8 +868,7 @@ export default class AppSearchSuper {
}

if(!this.membersList) {
this.membersList = new SortedUserList();
this.membersList.lazyLoadQueue = this.lazyLoadQueue;
this.membersList = new SortedUserList({lazyLoadQueue: this.lazyLoadQueue, rippleEnabled: false});
this.membersList.list.addEventListener('click', (e) => {
const li = findUpTag(e.target, 'LI');
if(!li) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/audio.ts
Expand Up @@ -272,7 +272,7 @@ function wrapAudio(audioEl: AudioElement) {

const senderTitle = audioEl.showSender ? appMessagesManager.getSenderToPeerText(message) : '';

let title = doc.type === 'voice' ? senderTitle : (doc.audioTitle || doc.file_name);
let title = doc.type === 'voice' ? senderTitle : (doc.audioTitle || doc.fileName);
let subtitle: string;

if(doc.type === 'voice') {
Expand Down
2 changes: 1 addition & 1 deletion src/components/chat/audio.ts
Expand Up @@ -56,7 +56,7 @@ export default class ChatAudio extends PinnedContainer {
//subtitle = 'Voice message';
subtitle = formatDate(message.date, false, false);
} else {
title = doc.audioTitle || doc.file_name;
title = doc.audioTitle || doc.fileName;
subtitle = doc.audioPerformer ? RichTextProcessor.wrapPlainText(doc.audioPerformer) : 'Unknown Artist';
}

Expand Down
2 changes: 2 additions & 0 deletions src/components/popups/newMedia.ts
Expand Up @@ -20,6 +20,7 @@ import calcImageInBox from "../../helpers/calcImageInBox";
import isSendShortcutPressed from "../../helpers/dom/isSendShortcutPressed";
import placeCaretAtEnd from "../../helpers/dom/placeCaretAtEnd";
import rootScope from "../../lib/rootScope";
import RichTextProcessor from "../../lib/richtextprocessor";

type SendFileParams = Partial<{
file: File,
Expand Down Expand Up @@ -298,6 +299,7 @@ export default class PopupNewMedia extends PopupElement {
_: 'document',
file: file,
file_name: file.name || '',
fileName: file.name ? RichTextProcessor.wrapEmojiText(file.name) : '',
size: file.size,
type: isPhoto ? 'photo' : 'doc'
} as MyDocument;
Expand Down
14 changes: 12 additions & 2 deletions src/components/sidebarLeft/index.ts
Expand Up @@ -575,12 +575,16 @@ export class SettingSection {
constructor(options: {
name?: LangPackKey,
caption?: LangPackKey | true,
noDelimiter?: boolean
noDelimiter?: boolean,
fakeGradientDelimiter?: boolean
}) {
this.container = document.createElement('div');
this.container.classList.add('sidebar-left-section');

if(!options.noDelimiter) {
if(options.fakeGradientDelimiter) {
this.container.append(generateDelimiter());
this.container.classList.add('with-fake-delimiter');
} else if(!options.noDelimiter) {
const hr = document.createElement('hr');
this.container.append(hr);
} else {
Expand Down Expand Up @@ -620,6 +624,12 @@ export const generateSection = (appendTo: Scrollable, name?: LangPackKey, captio
return section.content;
};

export const generateDelimiter = () => {
const delimiter = document.createElement('div');
delimiter.classList.add('gradient-delimiter');
return delimiter;
};

const appSidebarLeft = new AppSidebarLeft();
MOUNT_CLASS_TO.appSidebarLeft = appSidebarLeft;
export default appSidebarLeft;
2 changes: 1 addition & 1 deletion src/components/sidebarLeft/tabs/archivedTab.ts
Expand Up @@ -17,7 +17,7 @@ export default class AppArchivedTab extends SliderSuperTab {

if(!appDialogsManager.chatLists[AppArchivedTab.filterId]) {
const chatList = appDialogsManager.createChatList();
appDialogsManager.generateScrollable(chatList, AppArchivedTab.filterId);
appDialogsManager.generateScrollable(chatList, AppArchivedTab.filterId).container.append(chatList);
appDialogsManager.setListClickListener(chatList, null, true);
//appDialogsManager.setListClickListener(archivedChatList, null, true); // * to test peer changing
}
Expand Down
37 changes: 10 additions & 27 deletions src/components/sidebarLeft/tabs/contacts.ts
Expand Up @@ -8,7 +8,6 @@ import { SliderSuperTab } from "../../slider";
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import appUsersManager from "../../../lib/appManagers/appUsersManager";
import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
import rootScope from "../../../lib/rootScope";
import InputSearch from "../../inputSearch";
import { isMobile } from "../../../helpers/userAgent";
import { canFocus } from "../../../helpers/dom/canFocus";
Expand Down Expand Up @@ -67,50 +66,34 @@ export default class AppContactsTab extends SliderSuperTab {
if(this.promise) return this.promise;
this.scrollable.onScrolledBottom = null;

this.promise = appUsersManager.getContacts(query).then(_contacts => {
this.promise = appUsersManager.getContacts(query, undefined, 'online').then(contacts => {
this.promise = null;

if(!this.alive) {
//console.warn('user closed contacts before it\'s loaded');
return;
}

const contacts = [..._contacts];

if(!query) {
contacts.findAndSplice(u => u === rootScope.myId);
}
/* if(query && 'saved messages'.includes(query.toLowerCase())) {
contacts.unshift(rootScope.myID);
} */

let sorted = contacts
.map(userId => {
let user = appUsersManager.getUser(userId);
let status = appUsersManager.getUserStatusForSort(user.status);

return {user, status};
})
.sort((a, b) => b.status - a.status);

let renderPage = () => {
let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
let arr = sorted.splice(0, pageCount); // надо splice!
const pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
const arr = contacts.splice(0, pageCount); // надо splice!

arr.forEach(({user}) => {
let {dialog, dom} = appDialogsManager.addDialogNew({
dialog: user.id,
arr.forEach((peerId) => {
const {dom} = appDialogsManager.addDialogNew({
dialog: peerId,
container: this.list,
drawStatus: false,
avatarSize: 48,
autonomous: true
});

let status = appUsersManager.getUserStatusString(user.id);
const status = appUsersManager.getUserStatusString(peerId);
dom.lastMessageSpan.append(status);
});

if(!sorted.length) renderPage = undefined;
if(!contacts.length) {
renderPage = undefined;
}
};

renderPage();
Expand Down
2 changes: 1 addition & 1 deletion src/components/sidebarRight/tabs/groupPermissions.ts
Expand Up @@ -201,7 +201,7 @@ export default class AppGroupPermissionsTab extends SliderSuperTabEventable {
const c = section.generateContentElement();
c.classList.add('chatlist-container');

const list = appDialogsManager.createChatList();
const list = appDialogsManager.createChatList({new: true});
c.append(list);

attachClickEvent(list, (e) => {
Expand Down
7 changes: 2 additions & 5 deletions src/components/sidebarRight/tabs/sharedMedia.ts
Expand Up @@ -26,7 +26,7 @@ import { Chat, Message, MessageAction, ChatFull, Photo } from "../../../layer";
import Button from "../../button";
import ButtonIcon from "../../buttonIcon";
import I18n, { i18n, LangPackKey } from "../../../lib/langPack";
import { SettingSection } from "../../sidebarLeft";
import { generateDelimiter, SettingSection } from "../../sidebarLeft";
import Row from "../../row";
import { copyTextToClipboard } from "../../../helpers/clipboard";
import { toast, toastNew } from "../../toast";
Expand Down Expand Up @@ -572,10 +572,7 @@ class PeerProfile {

this.section.content.append(this.phone.container, this.username.container, this.bio.container, this.notifications.container);

const delimiter = document.createElement('div');
delimiter.classList.add('gradient-delimiter');

this.element.append(this.section.container, delimiter);
this.element.append(this.section.container, generateDelimiter());

this.notifications.checkboxField.input.addEventListener('change', (e) => {
if(!e.isTrusted) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/sidebarRight/tabs/userPermissions.ts
Expand Up @@ -36,7 +36,7 @@ export default class AppUserPermissionsTab extends SliderSuperTabEventable {
div.classList.add('chatlist-container');
section.content.insertBefore(div, section.title);

const list = appDialogsManager.createChatList();
const list = appDialogsManager.createChatList({new: true});
div.append(list);

const {dom} = appDialogsManager.addDialogNew({
Expand Down
27 changes: 19 additions & 8 deletions src/components/sortedUserList.ts
Expand Up @@ -12,21 +12,32 @@ import { insertInDescendSortedArray } from "../helpers/array";
import isInDOM from "../helpers/dom/isInDOM";
import positionElementByIndex from "../helpers/dom/positionElementByIndex";
import replaceContent from "../helpers/dom/replaceContent";
import { safeAssign } from "../helpers/object";

type SortedUser = {
peerId: number,
status: number,
dom: DialogDom
};
export default class SortedUserList {
public static SORT_INTERVAL = 30e3;
protected static SORT_INTERVAL = 30e3;
protected users: Map<number, SortedUser>;
protected sorted: Array<SortedUser>;
public list: HTMLUListElement;
public users: Map<number, SortedUser>;
public sorted: Array<SortedUser>;
public lazyLoadQueue: LazyLoadQueueIntersector;

protected lazyLoadQueue: LazyLoadQueueIntersector;
protected avatarSize = 48;
protected rippleEnabled = true;

constructor() {
this.list = appDialogsManager.createChatList();
constructor(options: Partial<{
lazyLoadQueue: SortedUserList['lazyLoadQueue'],
avatarSize: SortedUserList['avatarSize'],
rippleEnabled: SortedUserList['rippleEnabled'],
new: boolean
}> = {}) {
safeAssign(this, options);

this.list = appDialogsManager.createChatList({new: options.new});

this.users = new Map();
this.sorted = [];
Expand Down Expand Up @@ -76,10 +87,10 @@ export default class SortedUserList {
dialog: peerId,
container: false,
drawStatus: false,
avatarSize: 48,
avatarSize: this.avatarSize,
autonomous: true,
meAsSaved: false,
rippleEnabled: false,
rippleEnabled: this.rippleEnabled,
lazyLoadQueue: this.lazyLoadQueue
});

Expand Down
2 changes: 1 addition & 1 deletion src/components/wrappers.ts
Expand Up @@ -507,7 +507,7 @@ export function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showS
}

//let fileName = stringMiddleOverflow(doc.file_name || 'Unknown.file', 26);
let fileName = doc.file_name || 'Unknown.file';
let fileName = doc.fileName || 'Unknown.file';
let size = formatBytes(doc.size);

if(withTime) {
Expand Down
1 change: 1 addition & 0 deletions src/layer.d.ts
Expand Up @@ -3133,6 +3133,7 @@ export namespace Document {
h?: number,
w?: number,
file_name?: string,
fileName?: string,
file?: File,
duration?: number,
audioTitle?: string,
Expand Down

0 comments on commit 11d2fe0

Please sign in to comment.