From 9d55ead58241dc29a14b987102db28a5c653fd5c Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 22 Aug 2025 03:22:19 +0300 Subject: [PATCH 1/2] defParamCharset-config-added --- README.md | 3 +- doc/README-ar.md | 3 +- doc/README-es.md | 3 +- doc/README-fr.md | 3 +- doc/README-ko.md | 3 +- doc/README-pt-br.md | 3 +- doc/README-ru.md | 3 +- doc/README-uz.md | 3 +- doc/README-vi.md | 3 +- doc/README-zh-cn.md | 3 +- index.js | 3 + lib/make-middleware.js | 8 +- test/def-param-charset.js | 332 ++++++++++++++++++++++++++++++++++++++ 13 files changed, 362 insertions(+), 11 deletions(-) create mode 100644 test/def-param-charset.js diff --git a/README.md b/README.md index 1e062ee7..6d0ed94b 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ Key | Description `fileFilter` | Function to control which files are accepted `limits` | Limits of the uploaded data `preservePath` | Keep the full path of files instead of just the base name +`defParamCharset` | Default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). Default: `'latin1'` In an average web app, only `dest` might be required, and configured as shown in the following example. @@ -345,4 +346,4 @@ For information on how to build your own storage engine, see [Multer Storage Eng [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-ar.md b/doc/README-ar.md index ad577552..0b7a9149 100644 --- a/doc/README-ar.md +++ b/doc/README-ar.md @@ -126,6 +126,7 @@ app.post('/profile', upload.none(), function (req, res, next) { `fileFilter` | دالة للسيطرة على الملفات التي يتم قبولها `limits` | حدود البيانات التي تم تحميلها `preservePath` | الاحتفظ بالمسار الكامل للملفات بدلاً من الاسم الأساسي +`defParamCharset` | مجموعة الأحرف الافتراضية لاستخدامها لقيم معاملات رأس الجزء (مثل اسم الملف) التي ليست معاملات موسعة (لا تحتوي على مجموعة أحرف صريحة). الافتراضي: `'latin1'` في تطبيق ويب متوسط ​​، قد تكون هناك حاجة فقط إلى `dest`، وتكوينها كما هو موضح في المثال التالي : @@ -318,4 +319,4 @@ app.post('/profile', function (req, res) { [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-es.md b/doc/README-es.md index 91f7be2b..728d8193 100644 --- a/doc/README-es.md +++ b/doc/README-es.md @@ -135,6 +135,7 @@ Clave (key) | Descripción `fileFilter` | Función para controlar qué archivos son aceptados `limits` | Límites de los datos subidos `preservePath` | Mantiene la ruta completa de la ubicación de los archivos, en vez de sólo sus nombres +`defParamCharset` | Conjunto de caracteres por defecto para usar en valores de parámetros de encabezados de partes (ej. nombre de archivo) que no son parámetros extendidos (que contienen un conjunto de caracteres explícito). Por defecto: `'latin1'` En la aplicación web promedio es probable que sólo se requiera `dest`, siendo configurado como en el siguiente ejemplo: @@ -305,4 +306,4 @@ Para más información acerca de cómo construir tu propio mecanismo de almacena [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-fr.md b/doc/README-fr.md index d829e998..fcdde77e 100644 --- a/doc/README-fr.md +++ b/doc/README-fr.md @@ -137,6 +137,7 @@ Clé | Description `fileFilter` | Fonction pour contrôler quels fichiers sont acceptés `limits` | Limites des données téléchargées `preservePath` | Conservez le chemin complet des fichiers au lieu du nom de base uniquement +`defParamCharset` | Jeu de caractères par défaut à utiliser pour les valeurs des paramètres d'en-tête de partie (par exemple, nom de fichier) qui ne sont pas des paramètres étendus (qui contiennent un jeu de caractères explicite). Par défaut : `'latin1'` Dans une application Web moyenne, seul `dest` peut être requis et configuré comme indiqué dans l'exemple suivant. @@ -338,4 +339,4 @@ Pour plus d'informations sur la création de votre propre moteur de stockage, co [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-ko.md b/doc/README-ko.md index 63d33078..59c5a165 100644 --- a/doc/README-ko.md +++ b/doc/README-ko.md @@ -102,6 +102,7 @@ Key | Description `fileFilter` | 어떤 파일을 허용할지 제어하는 함수 `limits` | 업로드 된 데이터의 한도 `preservePath` | 파일의 base name 대신 보존할 파일의 전체 경로 +`defParamCharset` | 확장 매개변수가 아닌 부분 헤더 매개변수 값(예: 파일명)에 사용할 기본 문자 집합(명시적 문자 집합을 포함하지 않음). 기본값: `'latin1'` 보통의 웹 앱에서는 `dest` 옵션 정도만 필요할지도 모릅니다. 설정 방법은 아래의 예제에 나와있습니다. @@ -265,4 +266,4 @@ app.post('/profile', function (req, res) { [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-pt-br.md b/doc/README-pt-br.md index a2db4104..3179cf43 100644 --- a/doc/README-pt-br.md +++ b/doc/README-pt-br.md @@ -137,6 +137,7 @@ Key | Descrição `fileFilter` | Função para controlar quais arquivos são aceitos `limits` | Limites dos dados enviados `preservePath` | Mantenha o caminho completo dos arquivos em vez de apenas o nome base +`defParamCharset` | Conjunto de caracteres padrão para usar em valores de parâmetros de cabeçalho de parte (por exemplo, nome do arquivo) que não são parâmetros estendidos (que contêm um conjunto de caracteres explícito). Padrão: `'latin1'` Em um web app básico, somente o `dest` pode ser necessário, e configurado como mostrado no exemplo a seguir: @@ -312,4 +313,4 @@ Para obter informações sobre como criar seu próprio mecanismo de armazenament [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-ru.md b/doc/README-ru.md index 8c968b13..484b7d8f 100644 --- a/doc/README-ru.md +++ b/doc/README-ru.md @@ -109,6 +109,7 @@ Multer принимает объект с опциями. Базовая опц `fileFilter` | Функция для контроля принятия файлов `limits` | Ограничения по загрузке `preservePath` | Сохранять полный путь к файлам вместо только базового имени +`defParamCharset` | Кодировка по умолчанию для значений параметров заголовков частей (например, имя файла), которые не являются расширенными параметрами (не содержат явную кодировку). По умолчанию: `'latin1'` Обычно для веб-приложения нужно обязательно переопределить `dest`, как показано в примере ниже. @@ -275,4 +276,4 @@ app.post('/profile', function (req, res) { [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-uz.md b/doc/README-uz.md index 9c37cb36..0054d2f4 100644 --- a/doc/README-uz.md +++ b/doc/README-uz.md @@ -113,6 +113,7 @@ Kalit(key) | Ta'rif `fileFilter` | Qaysi fayllar qabul qilinishini boshqarish funksiyasi `limits` | Yuklash chegarasi `preservePath` | Asosiy nom o'rniga fayllarning to'liq yo'lini saqlash +`defParamCharset` | Kengaytirilgan parametrlar bo'lmagan qism sarlavha parametrlari qiymatlari (masalan, fayl nomi) uchun ishlatish uchun standart belgilar to'plami (aniq belgilar to'plamini o'z ichiga olmaydi). Standart: `'latin1'` O'rtacha veb-ilovada faqat `dest` kerak bo'lishi mumkin va quyidagicha sozlanishi mumkin @@ -280,4 +281,4 @@ O'zingizning saqlash dvigatelingizni qanday yaratish haqida ma'lumot olish: [Max [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-vi.md b/doc/README-vi.md index 977858c6..50a7d6e7 100644 --- a/doc/README-vi.md +++ b/doc/README-vi.md @@ -117,6 +117,7 @@ Dưới đây là các tùy chọn mà bạn có thể sử dụng: | `fileFilter` | Hàm để xử lý chỉ những file nào mới được chấp nhận | | `limits` | Giới hạn dung lượng file được upload | | `preservePath` | Giữ đầy đủ đường dẫn tới file thay vì chỉ tên file | +| `defParamCharset` | Bộ ký tự mặc định để sử dụng cho các giá trị tham số tiêu đề phần (ví dụ: tên tệp) không phải là tham số mở rộng (không chứa bộ ký tự rõ ràng). Mặc định: `'latin1'` | Nói chung với web app, chỉ `dest` mới cần khai báo, như bên dưới: @@ -297,4 +298,4 @@ app.post('/profile', function(req, res) { [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/doc/README-zh-cn.md b/doc/README-zh-cn.md index 31084d1c..5dcb6a97 100644 --- a/doc/README-zh-cn.md +++ b/doc/README-zh-cn.md @@ -104,6 +104,7 @@ Key | Description `fileFilter` | 文件过滤器,控制哪些文件可以被接受 `limits` | 限制上传的数据 `preservePath` | 保存包含文件名的完整文件路径 +`defParamCharset` | 用于部分标头参数值(例如文件名)的默认字符集,这些参数不是扩展参数(不包含显式字符集)。默认值:`'latin1'` 通常,一般的网页应用,只需要设置 `dest` 属性,像这样: @@ -270,4 +271,4 @@ app.post('/profile', function (req, res) { [npm-url]: https://npmjs.org/package/multer [npm-version-image]: https://badgen.net/npm/v/multer [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/multer/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer \ No newline at end of file +[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/multer diff --git a/index.js b/index.js index d5b67eba..1dbfaacb 100644 --- a/index.js +++ b/index.js @@ -19,6 +19,7 @@ function Multer (options) { this.limits = options.limits this.preservePath = options.preservePath + this.defParamCharset = options.defParamCharset || 'latin1' this.fileFilter = options.fileFilter || allowAll } @@ -47,6 +48,7 @@ Multer.prototype._makeMiddleware = function (fields, fileStrategy) { return { limits: this.limits, preservePath: this.preservePath, + defParamCharset: this.defParamCharset, storage: this.storage, fileFilter: wrappedFileFilter, fileStrategy: fileStrategy @@ -77,6 +79,7 @@ Multer.prototype.any = function () { return { limits: this.limits, preservePath: this.preservePath, + defParamCharset: this.defParamCharset, storage: this.storage, fileFilter: this.fileFilter, fileStrategy: 'ARRAY' diff --git a/lib/make-middleware.js b/lib/make-middleware.js index 18ea4274..b9f57ade 100644 --- a/lib/make-middleware.js +++ b/lib/make-middleware.js @@ -24,6 +24,7 @@ function makeMiddleware (setup) { var fileFilter = options.fileFilter var fileStrategy = options.fileStrategy var preservePath = options.preservePath + var defParamCharset = options.defParamCharset req.body = Object.create(null) @@ -34,7 +35,12 @@ function makeMiddleware (setup) { var busboy try { - busboy = Busboy({ headers: req.headers, limits: limits, preservePath: preservePath }) + busboy = Busboy({ + headers: req.headers, + limits: limits, + preservePath: preservePath, + defParamCharset: defParamCharset + }) } catch (err) { return next(err) } diff --git a/test/def-param-charset.js b/test/def-param-charset.js new file mode 100644 index 00000000..d292c9b4 --- /dev/null +++ b/test/def-param-charset.js @@ -0,0 +1,332 @@ +/* eslint-env mocha */ + +var assert = require('assert') +var stream = require('stream') + +var multer = require('../') +var temp = require('fs-temp') +var rimraf = require('rimraf') + +describe('defParamCharset', function () { + var uploadDir, upload + + beforeEach(function (done) { + temp.mkdir(function (err, path) { + if (err) return done(err) + + var storage = multer.diskStorage({ + destination: path, + filename: function (req, file, cb) { + cb(null, file.originalname) + } + }) + + uploadDir = path + upload = multer({ storage: storage }) + done() + }) + }) + + afterEach(function (done) { + rimraf(uploadDir, done) + }) + + it('should use latin1 as default charset for non-extended parameters', function (done) { + var req = new stream.PassThrough() + var boundary = 'AaB03x' + + // Create a filename with latin1 characters (e.g., café encoded as latin1) + // In latin1: é = 0xE9 + var bodyParts = [ + '--' + boundary, + 'Content-Disposition: form-data; name="testfile"; filename="caf', + '.txt"', + 'Content-Type: text/plain', + '', + 'test file content', + '--' + boundary + '--' + ] + + // Create buffer with proper latin1 encoding + var bodyBuffer = Buffer.concat([ + Buffer.from(bodyParts[0] + '\r\n', 'ascii'), + Buffer.from(bodyParts[1], 'ascii'), + Buffer.from([0xE9]), // é in latin1 + Buffer.from(bodyParts[2] + '\r\n', 'ascii'), + Buffer.from(bodyParts[3] + '\r\n', 'ascii'), + Buffer.from(bodyParts[4] + '\r\n', 'ascii'), + Buffer.from(bodyParts[5] + '\r\n', 'ascii'), + Buffer.from(bodyParts[6], 'ascii') + ]) + + req.headers = { + 'content-type': 'multipart/form-data; boundary=' + boundary, + 'content-length': bodyBuffer.length + } + + req.end(bodyBuffer) + + upload.single('testfile')(req, null, function (err) { + assert.ifError(err) + + // With latin1 (default), the filename should be interpreted as latin1 + assert.strictEqual(req.file.originalname, 'café.txt') + assert.strictEqual(req.file.fieldname, 'testfile') + + done() + }) + }) + + it('should use custom charset when defParamCharset is specified', function (done) { + var customUpload = multer({ + storage: multer.diskStorage({ + destination: uploadDir, + filename: function (req, file, cb) { + cb(null, file.originalname) + } + }), + defParamCharset: 'utf8' + }) + + var req = new stream.PassThrough() + var boundary = 'AaB03x' + + // Create a filename with UTF-8 characters (e.g., café encoded as UTF-8) + // In UTF-8: é = 0xC3 0xA9 + var bodyParts = [ + '--' + boundary, + 'Content-Disposition: form-data; name="testfile"; filename="caf', + '.txt"', + 'Content-Type: text/plain', + '', + 'test file content', + '--' + boundary + '--' + ] + + // Create buffer with proper UTF-8 encoding + var bodyBuffer = Buffer.concat([ + Buffer.from(bodyParts[0] + '\r\n', 'ascii'), + Buffer.from(bodyParts[1], 'ascii'), + Buffer.from([0xC3, 0xA9]), // é in UTF-8 + Buffer.from(bodyParts[2] + '\r\n', 'ascii'), + Buffer.from(bodyParts[3] + '\r\n', 'ascii'), + Buffer.from(bodyParts[4] + '\r\n', 'ascii'), + Buffer.from(bodyParts[5] + '\r\n', 'ascii'), + Buffer.from(bodyParts[6], 'ascii') + ]) + + req.headers = { + 'content-type': 'multipart/form-data; boundary=' + boundary, + 'content-length': bodyBuffer.length + } + + req.end(bodyBuffer) + + customUpload.single('testfile')(req, null, function (err) { + assert.ifError(err) + + // With utf8, the filename should be interpreted as utf8 + assert.strictEqual(req.file.originalname, 'café.txt') + assert.strictEqual(req.file.fieldname, 'testfile') + + done() + }) + }) + + it('should not affect extended parameters with explicit charset', function (done) { + var customUpload = multer({ + storage: multer.diskStorage({ + destination: uploadDir, + filename: function (req, file, cb) { + cb(null, file.originalname) + } + }), + defParamCharset: 'ascii' // This should be ignored for extended parameters + }) + + var req = new stream.PassThrough() + var boundary = 'AaB03x' + + var body = [ + '--' + boundary, + // Extended parameter with explicit UTF-8 charset should override defParamCharset + 'Content-Disposition: form-data; name="testfile"; filename*=utf-8\'\'caf%C3%A9.txt', + 'Content-Type: text/plain', + '', + 'test file content', + '--' + boundary + '--' + ].join('\r\n') + + req.headers = { + 'content-type': 'multipart/form-data; boundary=' + boundary, + 'content-length': body.length + } + + req.end(body) + + customUpload.single('testfile')(req, null, function (err) { + assert.ifError(err) + + // Extended parameter should use its own charset (UTF-8), not defParamCharset + assert.strictEqual(req.file.originalname, 'café.txt') + assert.strictEqual(req.file.fieldname, 'testfile') + + done() + }) + }) + + it('should handle different charsets correctly', function (done) { + var customUpload = multer({ + storage: multer.diskStorage({ + destination: uploadDir, + filename: function (req, file, cb) { + cb(null, file.originalname) + } + }), + defParamCharset: 'iso-8859-1' // Same as latin1 + }) + + var req = new stream.PassThrough() + var boundary = 'AaB03x' + + // Test with ISO-8859-1 encoded characters + var bodyParts = [ + '--' + boundary, + 'Content-Disposition: form-data; name="testfile"; filename="test', + '.txt"', + 'Content-Type: text/plain', + '', + 'test file content', + '--' + boundary + '--' + ] + + // Create buffer with proper ISO-8859-1 encoding + var bodyBuffer = Buffer.concat([ + Buffer.from(bodyParts[0] + '\r\n', 'ascii'), + Buffer.from(bodyParts[1], 'ascii'), + Buffer.from([0xF1]), // ñ in ISO-8859-1 + Buffer.from(bodyParts[2] + '\r\n', 'ascii'), + Buffer.from(bodyParts[3] + '\r\n', 'ascii'), + Buffer.from(bodyParts[4] + '\r\n', 'ascii'), + Buffer.from(bodyParts[5] + '\r\n', 'ascii'), + Buffer.from(bodyParts[6], 'ascii') + ]) + + req.headers = { + 'content-type': 'multipart/form-data; boundary=' + boundary, + 'content-length': bodyBuffer.length + } + + req.end(bodyBuffer) + + customUpload.single('testfile')(req, null, function (err) { + assert.ifError(err) + + // Should correctly decode the ñ character + assert.strictEqual(req.file.originalname, 'testñ.txt') + assert.strictEqual(req.file.fieldname, 'testfile') + + done() + }) + }) + + it('should work with memory storage', function (done) { + var memoryUpload = multer({ + storage: multer.memoryStorage(), + defParamCharset: 'utf8' + }) + + var req = new stream.PassThrough() + var boundary = 'AaB03x' + + var bodyParts = [ + '--' + boundary, + 'Content-Disposition: form-data; name="testfile"; filename="test', + '.txt"', + 'Content-Type: text/plain', + '', + 'test file content', + '--' + boundary + '--' + ] + + // Create buffer with proper UTF-8 encoding + var bodyBuffer = Buffer.concat([ + Buffer.from(bodyParts[0] + '\r\n', 'ascii'), + Buffer.from(bodyParts[1], 'ascii'), + Buffer.from([0xC3, 0xA9]), // é in UTF-8 + Buffer.from(bodyParts[2] + '\r\n', 'ascii'), + Buffer.from(bodyParts[3] + '\r\n', 'ascii'), + Buffer.from(bodyParts[4] + '\r\n', 'ascii'), + Buffer.from(bodyParts[5] + '\r\n', 'ascii'), + Buffer.from(bodyParts[6], 'ascii') + ]) + + req.headers = { + 'content-type': 'multipart/form-data; boundary=' + boundary, + 'content-length': bodyBuffer.length + } + + req.end(bodyBuffer) + + memoryUpload.single('testfile')(req, null, function (err) { + assert.ifError(err) + + assert.strictEqual(req.file.originalname, 'testé.txt') + assert.strictEqual(req.file.fieldname, 'testfile') + assert.ok(Buffer.isBuffer(req.file.buffer)) + + done() + }) + }) + + it('should work with array uploads', function (done) { + var customUpload = multer({ + storage: multer.diskStorage({ + destination: uploadDir, + filename: function (req, file, cb) { + cb(null, file.originalname) + } + }), + defParamCharset: 'utf8' + }) + + var req = new stream.PassThrough() + var boundary = 'AaB03x' + + // Create buffer with proper UTF-8 encoding for both files + var bodyBuffer = Buffer.concat([ + Buffer.from('--' + boundary + '\r\n', 'ascii'), + Buffer.from('Content-Disposition: form-data; name="testfiles"; filename="file1', 'ascii'), + Buffer.from([0xC3, 0xA9]), // é in UTF-8 + Buffer.from('.txt"\r\n', 'ascii'), + Buffer.from('Content-Type: text/plain\r\n', 'ascii'), + Buffer.from('\r\n', 'ascii'), + Buffer.from('test file 1 content\r\n', 'ascii'), + Buffer.from('--' + boundary + '\r\n', 'ascii'), + Buffer.from('Content-Disposition: form-data; name="testfiles"; filename="file2', 'ascii'), + Buffer.from([0xC3, 0xB1]), // ñ in UTF-8 + Buffer.from('.txt"\r\n', 'ascii'), + Buffer.from('Content-Type: text/plain\r\n', 'ascii'), + Buffer.from('\r\n', 'ascii'), + Buffer.from('test file 2 content\r\n', 'ascii'), + Buffer.from('--' + boundary + '--', 'ascii') + ]) + + req.headers = { + 'content-type': 'multipart/form-data; boundary=' + boundary, + 'content-length': bodyBuffer.length + } + + req.end(bodyBuffer) + + customUpload.array('testfiles', 2)(req, null, function (err) { + assert.ifError(err) + + assert.strictEqual(req.files.length, 2) + assert.strictEqual(req.files[0].originalname, 'file1é.txt') + assert.strictEqual(req.files[1].originalname, 'file2ñ.txt') + + done() + }) + }) +}) From 6937df5f5c8922fa8a7c75afa3e3366ba58ef1b0 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 22 Aug 2025 03:46:55 +0300 Subject: [PATCH 2/2] codeql-workflow-typo --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 378619a3..f9653932 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -16,7 +16,7 @@ on: branches: ["main", "v2"] pull_request: # The branches below must be a subset of the branches above - branches: ["main", "v2] + branches: ["main", "v2"] schedule: - cron: "0 0 * * 1"