diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b657c8bba..7ddfa7338 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,9 @@ jobs: env: NODE_OPTIONS: --max-old-space-size=4096 run: | - npm ci + rm package-lock.json +          npm install -g npm@latest +          npm install npm run build npm run test:backend -- --coverage --coverage.reporter=json --coverage.reporter=json-summary --coverage.reporter=lcov diff --git a/src/backend/package.json b/src/backend/package.json index 7509ad040..ca0c36832 100644 --- a/src/backend/package.json +++ b/src/backend/package.json @@ -78,6 +78,7 @@ "sharp": "^0.34.3", "sharp-bmp": "^0.1.5", "sharp-ico": "^0.1.5", + "shescape": "^2.1.10", "socket.io": "^4.6.2", "socket.io-client": "^4.6.2", "ssh2": "^1.13.0", diff --git a/src/backend/src/routers/drivers/call.js b/src/backend/src/routers/drivers/call.js index e292ac810..100afb9a2 100644 --- a/src/backend/src/routers/drivers/call.js +++ b/src/backend/src/routers/drivers/call.js @@ -118,7 +118,7 @@ _handle_multipart = async (req) => { const Busboy = require('busboy'); const { PassThrough } = require('stream'); - const params = {}; + const params = Object.create(null); const files = []; let file_index = 0; @@ -140,7 +140,7 @@ _handle_multipart = async (req) => { let dst = params; for ( let i = 0; i < key_parts.length; i++ ) { if ( ! Object.prototype.hasOwnProperty.call(dst, key_parts[i]) ) { - dst[key_parts[i]] = {}; + dst[key_parts[i]] = Object.create(null); } if ( !dst[key_parts[i]] || typeof dst[key_parts[i]] !== 'object' || Array.isArray(dst[key_parts[i]]) ) { throw new Error(`Tried to set member of non-object: ${key_parts[i]} in ${fieldname}`); @@ -173,7 +173,12 @@ _handle_multipart = async (req) => { }; bb.on('field', (fieldname, value, _details) => { - const o = JSON.parse(value); + const o = JSON.parse(value, (key, val) => { + if ( val !== null && typeof val === 'object' && !Array.isArray(val) ) { + return Object.assign(Object.create(null), val); + } + return val; + }); for ( const k in o ) { on_field(k, o[k]); } diff --git a/src/backend/src/services/HostDiskUsageService.js b/src/backend/src/services/HostDiskUsageService.js index 65e1a562e..6bf4620fc 100644 --- a/src/backend/src/services/HostDiskUsageService.js +++ b/src/backend/src/services/HostDiskUsageService.js @@ -18,6 +18,7 @@ */ const BaseService = require('./BaseService'); const { execSync } = require('child_process'); +const { Shescape } = require('shescape'); const config = require('../config'); /** @@ -112,12 +113,14 @@ class HostDiskUsageService extends BaseService { // Get the mountpoint/drive of the current working directory in mac os get_darwin_mountpoint (directory) { - return execSync(`df -P "${directory}" | awk 'NR==2 {print $6}'`, { encoding: 'utf-8' }).trim(); + const shescape = new Shescape({ shell: 'bash', quote: true }); + return execSync(`df -P ${shescape.escape(directory)} | awk 'NR==2 {print $6}'`, { encoding: 'utf-8' }).trim(); } // Get the mountpoint/drive of the current working directory in linux get_linux_mountpint (directory) { - return execSync(`df -P "${directory}" | awk 'NR==2 {print $6}'`, { encoding: 'utf-8' }).trim(); + const shescape = new Shescape({ shell: 'bash', quote: true }); + return execSync(`df -P ${shescape.escape(directory)} | awk 'NR==2 {print $6}'`, { encoding: 'utf-8' }).trim(); // TODO: Implement for linux systems } @@ -128,13 +131,15 @@ class HostDiskUsageService extends BaseService { // Get the total drive capacity on the mountpoint/drive in mac os get_disk_capacity_darwin (mountpoint) { - const disk_info = execSync(`df -P "${mountpoint}" | awk 'NR==2 {print $2}'`, { encoding: 'utf-8' }).trim().split(' '); + const shescape = new Shescape({ shell: 'bash', quote: true }); + const disk_info = execSync(`df -P ${shescape.escape(mountpoint)} | awk 'NR==2 {print $2}'`, { encoding: 'utf-8' }).trim().split(' '); return parseInt(disk_info) * 512; } // Get the total drive capacity on the mountpoint/drive in linux get_disk_capacity_linux (mountpoint) { - const disk_info = execSync(`df -P "${mountpoint}" | awk 'NR==2 {print $2}'`, { encoding: 'utf-8' }).trim().split(' '); + const shescape = new Shescape({ shell: 'bash', quote: true }); + const disk_info = execSync(`df -P ${shescape.escape(mountpoint)} | awk 'NR==2 {print $2}'`, { encoding: 'utf-8' }).trim().split(' '); return parseInt(disk_info) * 1024; } @@ -145,13 +150,15 @@ class HostDiskUsageService extends BaseService { // Get the free space on the mountpoint/drive in mac os get_disk_use_darwin (mountpoint) { - const disk_info = execSync(`df -P "${mountpoint}" | awk 'NR==2 {print $4}'`, { encoding: 'utf-8' }).trim().split(' '); + const shescape = new Shescape({ shell: 'bash', quote: true }); + const disk_info = execSync(`df -P ${shescape.escape(mountpoint)} | awk 'NR==2 {print $4}'`, { encoding: 'utf-8' }).trim().split(' '); return parseInt(disk_info) * 512; } // Get the free space on the mountpoint/drive in linux get_disk_use_linux (mountpoint) { - const disk_info = execSync(`df -P "${mountpoint}" | awk 'NR==2 {print $4}'`, { encoding: 'utf-8' }).trim().split(' '); + const shescape = new Shescape({ shell: 'bash', quote: true }); + const disk_info = execSync(`df -P ${shescape.escape(mountpoint)} | awk 'NR==2 {print $4}'`, { encoding: 'utf-8' }).trim().split(' '); return parseInt(disk_info) * 1024; }