escape Markdown in x[y](z) enclosures
This commit is contained in:
parent
415322b3ba
commit
aca114644a
|
@ -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();
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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'
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user