@yuneta/gobj-js 7.28.0 → 7.29.0

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.
@@ -430,7 +430,7 @@
430
430
  }
431
431
  };
432
432
  function tab() {
433
- return " ".repeat(Math.max(1, __inside__ * 2));
433
+ return " ".repeat(Math.max(1, __inside__ * 4));
434
434
  }
435
435
  var __trace_machine_format__ = 1;
436
436
  function gobj_set_trace_machine_format(format) {
@@ -7547,28 +7547,43 @@
7547
7547
  * Build a URL/path from segments, ensuring exactly one '/'
7548
7548
  * between each part.
7549
7549
  *
7550
- * - The first segment keeps its leading '/' (absolute) or
7551
- * not (relative).
7552
- * - Trailing '/' is stripped from every segment.
7553
- * - Leading '/' is stripped from every segment except the first.
7550
+ * - The first segment is the ROOT: it keeps its leading '/'
7551
+ * (absolute) or not (relative), and its trailing '/' are
7552
+ * stripped -- but a root made only of '/' stays "/".
7553
+ * - Leading and trailing '/' are stripped from every later
7554
+ * segment, and duplicate '/' inside it are collapsed.
7555
+ * - '.' and '..' of the later segments are resolved, and '..'
7556
+ * never rises above the root: ("/store", "../../etc") is
7557
+ * "/store/etc".
7554
7558
  * - Empty/null/undefined segments are skipped.
7555
7559
  *
7556
- * Mirrors the C helper build_path() from gobj-c/src/helpers.c.
7560
+ * Mirrors the C helper build_path() from gobj-c/src/helpers.c
7561
+ * (tests/build_path.test.js pins the same cases). Up to 7.28.1
7562
+ * a root "/" was lost (("/", "tmp") gave "tmp") and '.'/'..'
7563
+ * were kept as they came.
7557
7564
  ************************************************************/
7558
7565
  function build_path(...segments) {
7559
- let result = "";
7560
- let i = 0;
7566
+ let root = null;
7567
+ let tail = [];
7561
7568
  for (let segment of segments) {
7562
7569
  if (segment == null || segment === "") continue;
7563
7570
  segment = String(segment);
7564
- if (i === 0) segment = segment.replace(/\/+$/, "");
7565
- else segment = segment.replace(/^\/+/, "").replace(/\/+$/, "");
7566
- if (segment === "") continue;
7567
- if (i > 0) result += "/";
7568
- result += segment;
7569
- i++;
7571
+ if (root === null) {
7572
+ root = segment.replace(/(.)\/+$/, "$1");
7573
+ continue;
7574
+ }
7575
+ for (let component of segment.split("/")) {
7576
+ if (component === "" || component === ".") continue;
7577
+ if (component === "..") {
7578
+ tail.pop();
7579
+ continue;
7580
+ }
7581
+ tail.push(component);
7582
+ }
7570
7583
  }
7571
- return result;
7584
+ if (root === null) return "";
7585
+ if (tail.length === 0) return root;
7586
+ return root + (root.endsWith("/") ? "" : "/") + tail.join("/");
7572
7587
  }
7573
7588
  /***************************************
7574
7589
  * Flat json (id -> value)