From 0182c4b32efafc85d1f4a38840345944501feaef Mon Sep 17 00:00:00 2001 From: Rob van Oostenrijk Date: Thu, 31 Jul 2025 22:26:36 +0400 Subject: [PATCH] fix: Ignore symbolic links in `data` during backup (#28132) Co-authored-by: Nerivec <62446222+Nerivec@users.noreply.github.com> --- lib/util/utils.ts | 17 ++++++++++++----- test/extensions/bridge.test.ts | 6 ++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/util/utils.ts b/lib/util/utils.ts index 34319abf2..62e1fea44 100644 --- a/lib/util/utils.ts +++ b/lib/util/utils.ts @@ -202,14 +202,21 @@ function containsControlCharacter(str: string): boolean { function getAllFiles(path_: string): string[] { const result = []; - for (let item of fs.readdirSync(path_)) { - item = path.join(path_, item); - if (fs.lstatSync(item).isFile()) { - result.push(item); + + for (const item of fs.readdirSync(path_, {withFileTypes: true})) { + if (item.isSymbolicLink()) { + continue; + } + + const fileName = path.join(path_, item.name); + + if (fs.lstatSync(fileName).isFile()) { + result.push(fileName); } else { - result.push(...getAllFiles(item)); + result.push(...getAllFiles(fileName)); } } + return result; } diff --git a/test/extensions/bridge.test.ts b/test/extensions/bridge.test.ts index 44d354914..3de2a6dae 100644 --- a/test/extensions/bridge.test.ts +++ b/test/extensions/bridge.test.ts @@ -9,6 +9,7 @@ import {CUSTOM_CLUSTERS, devices, groups, mockController as mockZHController, ev import assert from "node:assert"; import fs from "node:fs"; +import {platform} from "node:os"; import path from "node:path"; import stringify from "json-stable-stringify-without-jsonify"; import type {Mock} from "vitest"; @@ -3841,6 +3842,11 @@ describe("Extension: Bridge", () => { fs.writeFileSync(path.join(data.mockDir, "log", "log.log"), "test123"); fs.mkdirSync(path.join(data.mockDir, "ext_converters", "123")); fs.writeFileSync(path.join(data.mockDir, "ext_converters", "123", "myfile.js"), "test123"); + fs.symlinkSync( + path.join(data.mockDir, "ext_converters"), + path.join(data.mockDir, "ext_converters_sym"), + platform() === "win32" ? "junction" : "dir", + ); mockMQTTPublishAsync.mockClear(); mockMQTTEvents.message("zigbee2mqtt/bridge/request/backup", ""); await flushPromises();