From ea54cd04c1ff0e55651cd5fb1a83672acde68604 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 8 Jun 2021 09:33:03 +0200 Subject: Fix video upload with a capitalized ext --- server/helpers/core-utils.ts | 88 +++++++++++++++++++++++++++-------------- server/helpers/express-utils.ts | 4 +- server/helpers/image-utils.ts | 7 ++-- 3 files changed, 64 insertions(+), 35 deletions(-) (limited to 'server/helpers') diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts index b93868c12..b5bf2c92c 100644 --- a/server/helpers/core-utils.ts +++ b/server/helpers/core-utils.ts @@ -8,7 +8,7 @@ import { exec, ExecOptions } from 'child_process' import { BinaryToTextEncoding, createHash, randomBytes } from 'crypto' import { truncate } from 'lodash' -import { basename, isAbsolute, join, resolve } from 'path' +import { basename, extname, isAbsolute, join, resolve } from 'path' import * as pem from 'pem' import { pipeline } from 'stream' import { URL } from 'url' @@ -32,6 +32,18 @@ const objectConverter = (oldObject: any, keyConverter: (e: string) => string, va return newObject } +function mapToJSON (map: Map) { + const obj: any = {} + + for (const [ k, v ] of map) { + obj[k] = v + } + + return obj +} + +// --------------------------------------------------------------------------- + const timeTable = { ms: 1, second: 1000, @@ -110,6 +122,8 @@ export function parseBytes (value: string | number): number { } } +// --------------------------------------------------------------------------- + function sanitizeUrl (url: string) { const urlObject = new URL(url) @@ -129,6 +143,8 @@ function sanitizeHost (host: string, remoteScheme: string) { return host.replace(new RegExp(`:${toRemove}$`), '') } +// --------------------------------------------------------------------------- + function isTestInstance () { return process.env.NODE_ENV === 'test' } @@ -141,6 +157,8 @@ function getAppNumber () { return process.env.NODE_APP_INSTANCE } +// --------------------------------------------------------------------------- + let rootPath: string function root () { @@ -154,27 +172,19 @@ function root () { return rootPath } -function pageToStartAndCount (page: number, itemsPerPage: number) { - const start = (page - 1) * itemsPerPage +function buildPath (path: string) { + if (isAbsolute(path)) return path - return { start, count: itemsPerPage } + return join(root(), path) } -function mapToJSON (map: Map) { - const obj: any = {} - - for (const [ k, v ] of map) { - obj[k] = v - } +function getLowercaseExtension (filename: string) { + const ext = extname(filename) || '' - return obj + return ext.toLowerCase() } -function buildPath (path: string) { - if (isAbsolute(path)) return path - - return join(root(), path) -} +// --------------------------------------------------------------------------- // Consistent with .length, lodash truncate function is not function peertubeTruncate (str: string, options: { length: number, separator?: RegExp, omission?: string }) { @@ -189,6 +199,27 @@ function peertubeTruncate (str: string, options: { length: number, separator?: R return truncate(str, options) } +function pageToStartAndCount (page: number, itemsPerPage: number) { + const start = (page - 1) * itemsPerPage + + return { start, count: itemsPerPage } +} + +// --------------------------------------------------------------------------- + +type SemVersion = { major: number, minor: number, patch: number } +function parseSemVersion (s: string) { + const parsed = s.match(/^v?(\d+)\.(\d+)\.(\d+)$/i) + + return { + major: parseInt(parsed[1]), + minor: parseInt(parsed[2]), + patch: parseInt(parsed[3]) + } as SemVersion +} + +// --------------------------------------------------------------------------- + function sha256 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') { return createHash('sha256').update(str).digest(encoding) } @@ -197,6 +228,8 @@ function sha1 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') { return createHash('sha1').update(str).digest(encoding) } +// --------------------------------------------------------------------------- + function execShell (command: string, options?: ExecOptions) { return new Promise<{ err?: Error, stdout: string, stderr: string }>((res, rej) => { exec(command, options, (err, stdout, stderr) => { @@ -208,6 +241,8 @@ function execShell (command: string, options?: ExecOptions) { }) } +// --------------------------------------------------------------------------- + function promisify0 (func: (cb: (err: any, result: A) => void) => void): () => Promise { return function promisified (): Promise { return new Promise((resolve: (arg: A) => void, reject: (err: any) => void) => { @@ -233,17 +268,6 @@ function promisify2 (func: (arg1: T, arg2: U, cb: (err: any, result: A) } } -type SemVersion = { major: number, minor: number, patch: number } -function parseSemVersion (s: string) { - const parsed = s.match(/^v?(\d+)\.(\d+)\.(\d+)$/i) - - return { - major: parseInt(parsed[1]), - minor: parseInt(parsed[2]), - patch: parseInt(parsed[3]) - } as SemVersion -} - const randomBytesPromise = promisify1(randomBytes) const createPrivateKey = promisify1(pem.createPrivateKey) const getPublicKey = promisify1(pem.getPublicKey) @@ -259,17 +283,21 @@ export { getAppNumber, objectConverter, + mapToJSON, + root, - pageToStartAndCount, + buildPath, + getLowercaseExtension, sanitizeUrl, sanitizeHost, - buildPath, + execShell, + + pageToStartAndCount, peertubeTruncate, sha256, sha1, - mapToJSON, promisify0, promisify1, diff --git a/server/helpers/express-utils.ts b/server/helpers/express-utils.ts index 010c6961a..003e02818 100644 --- a/server/helpers/express-utils.ts +++ b/server/helpers/express-utils.ts @@ -1,9 +1,9 @@ import * as express from 'express' import * as multer from 'multer' -import { extname } from 'path' import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' import { CONFIG } from '../initializers/config' import { REMOTE_SCHEME } from '../initializers/constants' +import { getLowercaseExtension } from './core-utils' import { isArray } from './custom-validators/misc' import { logger } from './logger' import { deleteFileAndCatch, generateRandomString } from './utils' @@ -79,7 +79,7 @@ function createReqFiles ( filename: async (req, file, cb) => { let extension: string - const fileExtension = extname(file.originalname) + const fileExtension = getLowercaseExtension(file.originalname) const extensionFromMimetype = getExtFromMimetype(mimeTypes, file.mimetype) // Take the file extension if we don't understand the mime type diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts index 6f6f8d4da..122fb009d 100644 --- a/server/helpers/image-utils.ts +++ b/server/helpers/image-utils.ts @@ -1,7 +1,7 @@ import { copy, readFile, remove, rename } from 'fs-extra' import * as Jimp from 'jimp' -import { extname } from 'path' import { v4 as uuidv4 } from 'uuid' +import { getLowercaseExtension } from './core-utils' import { convertWebPToJPG, processGIF } from './ffmpeg-utils' import { logger } from './logger' @@ -15,7 +15,7 @@ async function processImage ( newSize: { width: number, height: number }, keepOriginal = false ) { - const extension = extname(path) + const extension = getLowercaseExtension(path) if (path === destination) { throw new Error('Jimp/FFmpeg needs an input path different that the output path.') @@ -61,7 +61,8 @@ async function jimpProcessor (path: string, destination: string, newSize: { widt await remove(destination) // Optimization if the source file has the appropriate size - if (await skipProcessing({ jimpInstance, newSize, imageBytes: inputBuffer.byteLength, inputExt, outputExt: extname(destination) })) { + const outputExt = getLowercaseExtension(destination) + if (skipProcessing({ jimpInstance, newSize, imageBytes: inputBuffer.byteLength, inputExt, outputExt })) { return copy(path, destination) } -- cgit v1.2.3