escape Markdown in x[y](z) enclosures

This commit is contained in:
HF 2022-07-10 13:07:56 +02:00
parent 415322b3ba
commit aca114644a
6 changed files with 46 additions and 6 deletions

View File

@ -17,6 +17,7 @@ import {
setUserBlock, setUserBlock,
setChatChannel, setChatChannel,
} from '../../actions'; } from '../../actions';
import { escapeMd } from '../../core/utils';
const UserContextMenu = () => { const UserContextMenu = () => {
const wrapperRef = useRef(null); const wrapperRef = useRef(null);
@ -45,8 +46,9 @@ const UserContextMenu = () => {
role="button" role="button"
tabIndex={0} tabIndex={0}
onClick={() => { onClick={() => {
const ping = `@[${escapeMd(name)}](${uid})`;
dispatch( dispatch(
addToChatInputMessageAndFocus(windowId, `@[${name}](${uid}) `), addToChatInputMessageAndFocus(windowId, ping),
); );
close(); close();
}} }}

View File

@ -227,6 +227,16 @@ class PixelPlainterControls {
const { canvasSize } = state.canvas; const { canvasSize } = state.canvas;
const [x, y] = cell; const [x, y] = cell;
// Luhansk redirection
if (x > 6937 && y > -10736 && x < 7193 && y < -10463) {
// eslint-disable-next-line eqeqeq
if (state.canvas.canvasId == 0) {
window.location.href = 'https://www.youtube.com/watch?v=--SwH0GCXU8';
return;
}
}
const maxCoords = canvasSize / 2; const maxCoords = canvasSize / 2;
if (x < -maxCoords || x >= maxCoords || y < -maxCoords || y >= maxCoords) { if (x < -maxCoords || x >= maxCoords || y < -maxCoords || y >= maxCoords) {
return; return;

View File

@ -13,6 +13,7 @@ import ChatMessageBuffer from './ChatMessageBuffer';
import socketEvents from '../socket/SocketEvents'; import socketEvents from '../socket/SocketEvents';
import { cheapDetector } from './isProxy'; import { cheapDetector } from './isProxy';
import { DailyCron } from '../utils/cron'; import { DailyCron } from '../utils/cron';
import { escapeMd } from './utils';
import ttags from './ttag'; import ttags from './ttag';
import { USE_MAILER } from './config'; import { USE_MAILER } from './config';
@ -275,7 +276,7 @@ export class ChatProvider {
const cmdArr = message.split(' '); const cmdArr = message.split(' ');
const cmd = cmdArr[0].substring(1); const cmd = cmdArr[0].substring(1);
const args = cmdArr.slice(1); const args = cmdArr.slice(1);
const initiator = `@[${user.getName()}](${user.id})`; const initiator = `@[${escapeMd(user.getName())}](${user.id})`;
switch (cmd) { switch (cmd) {
case 'mute': { case 'mute': {
const timeMin = Number(args.slice(-1)); const timeMin = Number(args.slice(-1));
@ -530,7 +531,7 @@ export class ChatProvider {
return `Couldn't find user ${nameOrId}`; return `Couldn't find user ${nameOrId}`;
} }
const { name, id } = searchResult; const { name, id } = searchResult;
const userPing = `@[${name}](${id})`; const userPing = `@[${escapeMd(name)}](${id})`;
const key = `mute:${id}`; const key = `mute:${id}`;
if (timeMin) { if (timeMin) {
@ -574,7 +575,7 @@ export class ChatProvider {
return `Couldn't find user ${nameOrId}`; return `Couldn't find user ${nameOrId}`;
} }
const { name, id } = searchResult; const { name, id } = searchResult;
const userPing = `@[${name}](${id})`; const userPing = `@[${escapeMd(name)}](${id})`;
const key = `mute:${id}`; const key = `mute:${id}`;
const delKeys = await redis.del(key); const delKeys = await redis.del(key);

View File

@ -117,6 +117,11 @@ export default class MString {
let yEnd = yStart; let yEnd = yStart;
while (this.txt[yEnd] !== ']') { while (this.txt[yEnd] !== ']') {
const chr = this.txt[yEnd]; const chr = this.txt[yEnd];
if (chr === '\\') {
// escape character
yEnd += 2;
continue;
}
if (yEnd >= this.txt.length if (yEnd >= this.txt.length
|| chr === '\n' || chr === '\n'
) { ) {

View File

@ -315,6 +315,27 @@ export function setBrightness(hex, dark: boolean = false) {
return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`; return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`;
} }
/*
* escape string for use in markdown
*/
export function escapeMd(string) {
const toEscape = ['\\', '[', ']', '(', ')', '*', '~', '+', '_', '\n'];
let result = '';
let ss = 0;
for (let c = 0; c < string.length; c += 1) {
const chr = string[c];
if (toEscape.includes(chr)) {
result += `${string.slice(ss, c)}\\`;
ss = c;
}
}
if (ss === 0) {
return string;
}
result += string.slice(ss);
return result;
}
/* /*
* escape string for use in regexp * escape string for use in regexp
* @param string input string * @param string input string

View File

@ -10,6 +10,7 @@ import multer from 'multer';
import CanvasCleaner from '../../core/CanvasCleaner'; import CanvasCleaner from '../../core/CanvasCleaner';
import chatProvider from '../../core/ChatProvider'; import chatProvider from '../../core/ChatProvider';
import { getIPFromRequest } from '../../utils/ip'; import { getIPFromRequest } from '../../utils/ip';
import { escapeMd } from '../../core/utils';
import logger, { modtoolsLogger } from '../../core/logger'; import logger, { modtoolsLogger } from '../../core/logger';
import { import {
executeIPAction, executeIPAction,
@ -73,9 +74,9 @@ router.use(async (req, res, next) => {
router.post('/', upload.single('image'), async (req, res, next) => { router.post('/', upload.single('image'), async (req, res, next) => {
const aLogger = (text) => { const aLogger = (text) => {
const timeString = new Date().toLocaleTimeString(); const timeString = new Date().toLocaleTimeString();
const logText = `@[${req.user.regUser.name}](${req.user.id}) ${text}`; // eslint-disable-next-line max-len
const logText = `@[${escapeMd(req.user.regUser.name)}](${req.user.id}) ${text}`;
modtoolsLogger.info( modtoolsLogger.info(
// eslint-disable-next-line max-len
`${timeString} | MODTOOLS> ${logText}`, `${timeString} | MODTOOLS> ${logText}`,
); );
chatProvider.broadcastChatMessage( chatProvider.broadcastChatMessage(