inibase 1.0.0-rc.102 → 1.0.0-rc.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/file.js +22 -10
  2. package/package.json +2 -2
package/dist/file.js CHANGED
@@ -5,10 +5,10 @@ import { createInterface } from "node:readline";
5
5
  import { Transform } from "node:stream";
6
6
  import { pipeline } from "node:stream/promises";
7
7
  import { createGunzip, createGzip } from "node:zlib";
8
+ import { spawn as spawnSync } from "node:child_process";
8
9
  import Inison from "inison";
9
10
  import { detectFieldType, isArrayOfObjects, isStringified, isNumber, isObject, } from "./utils.js";
10
11
  import { compare, encodeID, exec, gunzip, gzip } from "./utils.server.js";
11
- import { spawn } from "node:child_process";
12
12
  export const lock = async (folderPath, prefix) => {
13
13
  let lockFile = null;
14
14
  const lockFilePath = join(folderPath, `${prefix ?? ""}.locked`);
@@ -36,6 +36,10 @@ export const write = async (filePath, data) => {
36
36
  export const read = async (filePath) => filePath.endsWith(".gz")
37
37
  ? (await gunzip(await readFile(filePath, "utf8"))).toString()
38
38
  : await readFile(filePath, "utf8");
39
+ // Escaping function to safely handle special characters
40
+ function _escapeDoubleQuotes(arg) {
41
+ return arg.replace(/(["$`\\])/g, "\\$1"); // Escape double quotes, $, `, and \
42
+ }
39
43
  const _pipeline = async (filePath, rl, writeStream, transform) => {
40
44
  if (filePath.endsWith(".gz"))
41
45
  await pipeline(rl, transform, createGzip(), writeStream);
@@ -194,9 +198,10 @@ export async function get(filePath, lineNumbers, fieldType, fieldChildrenType, s
194
198
  }
195
199
  }
196
200
  else if (lineNumbers == -1) {
201
+ const escapedFilePath = `"${_escapeDoubleQuotes(filePath)}"`;
197
202
  const command = filePath.endsWith(".gz")
198
- ? `zcat ${filePath} | sed -n '$p'`
199
- : `sed -n '$p' ${filePath}`, foundedLine = (await exec(command)).stdout.trimEnd();
203
+ ? `zcat ${escapedFilePath} | sed -n '$p'`
204
+ : `sed -n '$p' ${escapedFilePath}`, foundedLine = (await exec(command)).stdout.trimEnd();
200
205
  if (foundedLine)
201
206
  lines[linesCount] = decode(foundedLine, fieldType, fieldChildrenType, secretKey);
202
207
  }
@@ -215,9 +220,10 @@ export async function get(filePath, lineNumbers, fieldType, fieldChildrenType, s
215
220
  }
216
221
  return [lines, linesCount];
217
222
  }
223
+ const escapedFilePath = `"${_escapeDoubleQuotes(filePath)}"`;
218
224
  const command = filePath.endsWith(".gz")
219
- ? `zcat ${filePath} | sed -n '${lineNumbers.join("p;")}p'`
220
- : `sed -n '${lineNumbers.join("p;")}p' ${filePath}`, foundedLines = (await exec(command)).stdout.trimEnd().split("\n");
225
+ ? `zcat "${escapedFilePath}" | sed -n '${lineNumbers.join("p;")}p'`
226
+ : `sed -n '${lineNumbers.join("p;")}p' "${escapedFilePath}"`, foundedLines = (await exec(command)).stdout.trimEnd().split("\n");
221
227
  let index = 0;
222
228
  for (const line of foundedLines) {
223
229
  lines[lineNumbers[index]] = decode(line, fieldType, fieldChildrenType, secretKey);
@@ -278,7 +284,7 @@ export const replace = async (filePath, replacements, totalItems) => {
278
284
  }
279
285
  else {
280
286
  return new Promise((resolve) => {
281
- const sedProcess = spawn("sed", [
287
+ const sedProcess = spawnSync("sed", [
282
288
  "-e",
283
289
  `s/.*/${replacements}/`,
284
290
  "-e",
@@ -347,9 +353,10 @@ export const append = async (filePath, data) => {
347
353
  await appendFile(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
348
354
  }
349
355
  else {
356
+ const escapedFileTempPath = `"${_escapeDoubleQuotes(fileTempPath)}"`;
350
357
  await exec(`echo $'${(Array.isArray(data) ? data.join("\n") : data)
351
358
  .toString()
352
- .replace(/'/g, "\\'")}' | gzip - >> ${fileTempPath}`);
359
+ .replace(/'/g, "\\'")}' | gzip - >> ${escapedFileTempPath}`);
353
360
  }
354
361
  }
355
362
  else
@@ -402,7 +409,10 @@ export const prepend = async (filePath, data) => {
402
409
  const fileChildTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/tmp_$1");
403
410
  try {
404
411
  await write(fileChildTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
405
- await exec(`cat ${fileChildTempPath} ${filePath} > ${fileTempPath}`);
412
+ const escapedFilePath = `"${_escapeDoubleQuotes(filePath)}"`;
413
+ const escapedFileTempPath = `"${_escapeDoubleQuotes(fileTempPath)}"`;
414
+ const escapedFileChildTempPath = `"${_escapeDoubleQuotes(fileChildTempPath)}"`;
415
+ await exec(`cat ${escapedFileChildTempPath} ${escapedFilePath} > ${escapedFileTempPath}`);
406
416
  }
407
417
  catch {
408
418
  return [fileTempPath, null];
@@ -439,9 +449,11 @@ export const remove = async (filePath, linesToDelete) => {
439
449
  throw new Error("UNVALID_LINE_NUMBERS");
440
450
  const fileTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/$1");
441
451
  try {
452
+ const escapedFilePath = `"${_escapeDoubleQuotes(filePath)}"`;
453
+ const escapedFileTempPath = `"${_escapeDoubleQuotes(fileTempPath)}"`;
442
454
  const command = filePath.endsWith(".gz")
443
- ? `zcat ${filePath} | sed "${linesToDelete.join("d;")}d" | gzip > ${fileTempPath}`
444
- : `sed "${linesToDelete.join("d;")}d" ${filePath} > ${fileTempPath}`;
455
+ ? `zcat ${escapedFilePath} | sed "${linesToDelete.join("d;")}d" | gzip > ${fileTempPath}`
456
+ : `sed "${linesToDelete.join("d;")}d" ${escapedFilePath} > ${escapedFileTempPath}`;
445
457
  await exec(command);
446
458
  return [fileTempPath, filePath];
447
459
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.102",
3
+ "version": "1.0.0-rc.103",
4
4
  "type": "module",
5
5
  "author": {
6
6
  "name": "Karim Amahtil",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "description": "A file-based & memory-efficient, serverless, ACID compliant, relational database management system",
21
21
  "engines": {
22
- "node": ">=16"
22
+ "node": ">=22"
23
23
  },
24
24
  "files": [
25
25
  "/dist"