@yuneta/gobj-js 7.26.19 → 7.26.21
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.
- package/README.md +29 -1
- package/dist/gobj-js.cjs.js +369 -40
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +988 -749
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +369 -40
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +977 -738
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +369 -40
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +1163 -924
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +369 -40
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +1163 -924
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/gobj-js.es.js
CHANGED
|
@@ -3435,6 +3435,11 @@ var SECRET_NAME_JOINED = [
|
|
|
3435
3435
|
"sessionkey",
|
|
3436
3436
|
"authdata"
|
|
3437
3437
|
];
|
|
3438
|
+
var SECRET_NAME_SEGMENTS = /* @__PURE__ */ new Set([
|
|
3439
|
+
"pass",
|
|
3440
|
+
"pin",
|
|
3441
|
+
"otp"
|
|
3442
|
+
]);
|
|
3438
3443
|
var NOT_SECRET_SEGMENTS = /* @__PURE__ */ new Set([
|
|
3439
3444
|
"endpoint",
|
|
3440
3445
|
"url",
|
|
@@ -3467,10 +3472,16 @@ function is_secret_name(name) {
|
|
|
3467
3472
|
if (typeof name !== "string" || name.length < 3) return false;
|
|
3468
3473
|
let lower = name.toLowerCase();
|
|
3469
3474
|
let hit = false;
|
|
3470
|
-
for (const
|
|
3475
|
+
for (const segment of lower.split(/[^a-z0-9]+/)) if (SECRET_NAME_SEGMENTS.has(segment)) {
|
|
3471
3476
|
hit = true;
|
|
3472
3477
|
break;
|
|
3473
3478
|
}
|
|
3479
|
+
if (!hit) {
|
|
3480
|
+
for (const part of SECRET_NAME_PARTS) if (lower.indexOf(part) >= 0) {
|
|
3481
|
+
hit = true;
|
|
3482
|
+
break;
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3474
3485
|
if (!hit) {
|
|
3475
3486
|
let joined = lower.replace(/[_\-. \t]/g, "");
|
|
3476
3487
|
for (const part of SECRET_NAME_JOINED) if (joined.indexOf(part) >= 0) {
|
|
@@ -3508,32 +3519,250 @@ function inline_secret_value_end(str, p, outer) {
|
|
|
3508
3519
|
}
|
|
3509
3520
|
}
|
|
3510
3521
|
/************************************************************
|
|
3511
|
-
* A
|
|
3512
|
-
*
|
|
3513
|
-
*
|
|
3514
|
-
*
|
|
3515
|
-
*
|
|
3522
|
+
* A credential by its SHAPE, whatever names it -- the C kernel's
|
|
3523
|
+
* jwt_len() / scheme_credential(), the shapes the agent's audit
|
|
3524
|
+
* record redacts, and the schemes of an HTTP Authorization:
|
|
3525
|
+
* - a JWT or a JWE: "eyJ" (the base64url of '{"') at the start
|
|
3526
|
+
* of a word, base64url, and a '.' after it -- three parts
|
|
3527
|
+
* joined by '.' (a JWS), five (a JWE), or fewer when a cap cut
|
|
3528
|
+
* it; the dots at the end of the run are not its own (a JWT
|
|
3529
|
+
* ends a sentence: "... eyJ.eyJ.sig.");
|
|
3530
|
+
* - the credential after the scheme word "Bearer" or "Basic"
|
|
3531
|
+
* (any case, a word of its own): scheme_credential().
|
|
3516
3532
|
************************************************************/
|
|
3533
|
+
var MASK_TOKEN_MIN = 8;
|
|
3534
|
+
var MASK_PROSE_MAX = 24;
|
|
3535
|
+
function is_ascii_alnum_code(code) {
|
|
3536
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
3537
|
+
}
|
|
3538
|
+
function is_ascii_letter_code(code) {
|
|
3539
|
+
return code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
3540
|
+
}
|
|
3541
|
+
function is_ascii_upper_code(code) {
|
|
3542
|
+
return code >= 65 && code <= 90;
|
|
3543
|
+
}
|
|
3544
|
+
function is_base64url_code(code) {
|
|
3545
|
+
return is_ascii_alnum_code(code) || code === 45 || code === 95;
|
|
3546
|
+
}
|
|
3547
|
+
function ascii_case_equal(str, p, word) {
|
|
3548
|
+
if (str.length - p < word.length) return false;
|
|
3549
|
+
for (let i = 0; i < word.length; i++) {
|
|
3550
|
+
let code = str.charCodeAt(p + i);
|
|
3551
|
+
if (code >= 65 && code <= 90) code += 32;
|
|
3552
|
+
if (code !== word.charCodeAt(i)) return false;
|
|
3553
|
+
}
|
|
3554
|
+
return true;
|
|
3555
|
+
}
|
|
3556
|
+
function jwt_len(str, p) {
|
|
3557
|
+
if (str.length - p < 3 || str[p] !== "e" || str[p + 1] !== "y" || str[p + 2] !== "J") return 0;
|
|
3558
|
+
if (p > 0 && (is_base64url_code(str.charCodeAt(p - 1)) || str[p - 1] === ".")) return 0;
|
|
3559
|
+
let e = p;
|
|
3560
|
+
let dotted = false;
|
|
3561
|
+
while (e < str.length && (is_base64url_code(str.charCodeAt(e)) || str[e] === ".")) {
|
|
3562
|
+
if (str[e] === ".") dotted = true;
|
|
3563
|
+
e++;
|
|
3564
|
+
}
|
|
3565
|
+
if (!dotted) return 0;
|
|
3566
|
+
while (str[e - 1] === ".") e--;
|
|
3567
|
+
return e - p;
|
|
3568
|
+
}
|
|
3569
|
+
function scheme_word_len(str, p) {
|
|
3570
|
+
if (p > 0 && is_ascii_alnum_code(str.charCodeAt(p - 1))) return 0;
|
|
3571
|
+
for (const scheme of ["bearer", "basic"]) {
|
|
3572
|
+
const n = scheme.length;
|
|
3573
|
+
if (str.length - p > n && ascii_case_equal(str, p, scheme) && (str[p + n] === " " || str[p + n] === " ")) return n;
|
|
3574
|
+
}
|
|
3575
|
+
return 0;
|
|
3576
|
+
}
|
|
3577
|
+
function code_points(str, w, n) {
|
|
3578
|
+
let count = 0;
|
|
3579
|
+
for (let i = w; i < w + n; i++) {
|
|
3580
|
+
const code = str.charCodeAt(i);
|
|
3581
|
+
if (code < 56320 || code > 57343) count++;
|
|
3582
|
+
}
|
|
3583
|
+
return count;
|
|
3584
|
+
}
|
|
3585
|
+
function is_prose_word(str, w, n) {
|
|
3586
|
+
if (n === 0 || n >= MASK_PROSE_MAX) return false;
|
|
3587
|
+
let i = w;
|
|
3588
|
+
const end = w + n;
|
|
3589
|
+
while (true) {
|
|
3590
|
+
let r = i;
|
|
3591
|
+
let upper_rest = true;
|
|
3592
|
+
let lower_rest = true;
|
|
3593
|
+
while (r < end && is_ascii_letter_code(str.charCodeAt(r))) {
|
|
3594
|
+
if (r > i) {
|
|
3595
|
+
if (is_ascii_upper_code(str.charCodeAt(r))) lower_rest = false;
|
|
3596
|
+
else upper_rest = false;
|
|
3597
|
+
}
|
|
3598
|
+
r++;
|
|
3599
|
+
}
|
|
3600
|
+
if (r === i) return false;
|
|
3601
|
+
if (!lower_rest && !(upper_rest && is_ascii_upper_code(str.charCodeAt(i)))) return false;
|
|
3602
|
+
if (r === end) return true;
|
|
3603
|
+
if (str[r] !== "-" && str[r] !== "." && str[r] !== "/" || r + 1 === end) return false;
|
|
3604
|
+
i = r + 1;
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
function base64_digit(code) {
|
|
3608
|
+
if (code >= 65 && code <= 90) return code - 65;
|
|
3609
|
+
if (code >= 97 && code <= 122) return code - 97 + 26;
|
|
3610
|
+
if (code >= 48 && code <= 57) return code - 48 + 52;
|
|
3611
|
+
if (code === 43) return 62;
|
|
3612
|
+
if (code === 47) return 63;
|
|
3613
|
+
return -1;
|
|
3614
|
+
}
|
|
3615
|
+
function is_basic_credential(str, w, n) {
|
|
3616
|
+
let bits = 0;
|
|
3617
|
+
let n_bits = 0;
|
|
3618
|
+
for (let i = 0; i < n; i++) {
|
|
3619
|
+
const v = base64_digit(str.charCodeAt(w + i));
|
|
3620
|
+
if (v < 0) return false;
|
|
3621
|
+
bits = (bits << 6 | v) & 16383;
|
|
3622
|
+
n_bits += 6;
|
|
3623
|
+
if (n_bits >= 8) {
|
|
3624
|
+
n_bits -= 8;
|
|
3625
|
+
if ((bits >> n_bits & 255) === 58) return true;
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
return false;
|
|
3629
|
+
}
|
|
3630
|
+
var SCHEME_WORD_STOPS = " \r\n\"',;}]\0";
|
|
3631
|
+
function scheme_credential(str, p) {
|
|
3632
|
+
const n = scheme_word_len(str, p);
|
|
3633
|
+
if (!n) return [0, 0];
|
|
3634
|
+
const scheme = n === 5 ? "basic" : "bearer";
|
|
3635
|
+
let context = false;
|
|
3636
|
+
let t = p + n;
|
|
3637
|
+
while (t < str.length && (str[t] === " " || str[t] === " ")) t++;
|
|
3638
|
+
if (t < str.length && scheme_word_len(str, t) === n && ascii_case_equal(str, t, scheme)) {
|
|
3639
|
+
t += n;
|
|
3640
|
+
context = true;
|
|
3641
|
+
while (t < str.length && (str[t] === " " || str[t] === " ")) t++;
|
|
3642
|
+
}
|
|
3643
|
+
if (t >= str.length) return [0, 0];
|
|
3644
|
+
if (str[t] === "\"" || str[t] === "'") {
|
|
3645
|
+
let q = t + 1;
|
|
3646
|
+
while (q < str.length && str[q] !== str[t] && str[q] !== " " && str[q] !== " " && str[q] !== "\r" && str[q] !== "\n" && str[q] !== "\0") q++;
|
|
3647
|
+
if (q < str.length && str[q] === str[t] && q > t + 1) return [t - p, q + 1 - t];
|
|
3648
|
+
return [0, 0];
|
|
3649
|
+
}
|
|
3650
|
+
let e = t;
|
|
3651
|
+
while (e < str.length && SCHEME_WORD_STOPS.indexOf(str[e]) < 0) e++;
|
|
3652
|
+
if (e === t) return [0, 0];
|
|
3653
|
+
if (!context) {
|
|
3654
|
+
let w_end = e;
|
|
3655
|
+
while (w_end > t && str[w_end - 1] === ".") w_end--;
|
|
3656
|
+
const len = w_end - t;
|
|
3657
|
+
if (len === 0 || is_prose_word(str, t, len)) return [0, 0];
|
|
3658
|
+
if (n === 5) {
|
|
3659
|
+
if (!is_basic_credential(str, t, len)) return [0, 0];
|
|
3660
|
+
} else if (code_points(str, t, len) < MASK_TOKEN_MIN) return [0, 0];
|
|
3661
|
+
}
|
|
3662
|
+
return [t - p, e - t];
|
|
3663
|
+
}
|
|
3664
|
+
function shape_len(str, p) {
|
|
3665
|
+
const c = str[p];
|
|
3666
|
+
if (c === "e") return [0, jwt_len(str, p)];
|
|
3667
|
+
if (c === "b" || c === "B") return scheme_credential(str, p);
|
|
3668
|
+
return [0, 0];
|
|
3669
|
+
}
|
|
3670
|
+
function shape_len_7_26_9(str, p) {
|
|
3671
|
+
const c = str[p];
|
|
3672
|
+
if (c === "e") {
|
|
3673
|
+
if (str.length - p < 3 || str[p + 1] !== "y" || str[p + 2] !== "J") return [0, 0];
|
|
3674
|
+
if (p > 0 && (is_base64url_code(str.charCodeAt(p - 1)) || str[p - 1] === ".")) return [0, 0];
|
|
3675
|
+
let e = p;
|
|
3676
|
+
let dots = 0;
|
|
3677
|
+
while (e < str.length && (is_base64url_code(str.charCodeAt(e)) || str[e] === ".")) {
|
|
3678
|
+
if (str[e] === ".") dots++;
|
|
3679
|
+
e++;
|
|
3680
|
+
}
|
|
3681
|
+
while (str[e - 1] === ".") {
|
|
3682
|
+
e--;
|
|
3683
|
+
dots--;
|
|
3684
|
+
}
|
|
3685
|
+
return dots === 2 ? [0, e - p] : [0, 0];
|
|
3686
|
+
}
|
|
3687
|
+
if (c === "b" || c === "B") {
|
|
3688
|
+
if (str.length - p <= 6 || !ascii_case_equal(str, p, "bearer")) return [0, 0];
|
|
3689
|
+
if (p > 0 && is_ascii_alnum_code(str.charCodeAt(p - 1))) return [0, 0];
|
|
3690
|
+
let t = p + 6;
|
|
3691
|
+
if (str[t] !== " " && str[t] !== " ") return [0, 0];
|
|
3692
|
+
while (t < str.length && (str[t] === " " || str[t] === " ")) t++;
|
|
3693
|
+
let e = t;
|
|
3694
|
+
while (e < str.length && " \r\n'\",;}]\0".indexOf(str[e]) < 0) e++;
|
|
3695
|
+
return [t - p, e - t];
|
|
3696
|
+
}
|
|
3697
|
+
return [0, 0];
|
|
3698
|
+
}
|
|
3699
|
+
var COLON_VALUE_STOPS = " \r\n,;&)]}<>\"'\0";
|
|
3700
|
+
function colon_value_end(str, v) {
|
|
3701
|
+
if (v >= str.length) return v;
|
|
3702
|
+
const c = str[v];
|
|
3703
|
+
if (c === "\"" || c === "'") {
|
|
3704
|
+
let e = v + 1;
|
|
3705
|
+
while (e < str.length && str[e] !== c) {
|
|
3706
|
+
if (str[e] === "\\" && e + 1 < str.length) e++;
|
|
3707
|
+
e++;
|
|
3708
|
+
}
|
|
3709
|
+
return e < str.length ? e + 1 : str.length;
|
|
3710
|
+
}
|
|
3711
|
+
if (c === "{" || c === "[") {
|
|
3712
|
+
let depth = 0;
|
|
3713
|
+
let in_string = false;
|
|
3714
|
+
for (let e = v; e < str.length; e++) if (in_string) {
|
|
3715
|
+
if (str[e] === "\\" && e + 1 < str.length) e++;
|
|
3716
|
+
else if (str[e] === "\"") in_string = false;
|
|
3717
|
+
} else if (str[e] === "\"") in_string = true;
|
|
3718
|
+
else if (str[e] === "{" || str[e] === "[") depth++;
|
|
3719
|
+
else if (str[e] === "}" || str[e] === "]") {
|
|
3720
|
+
depth--;
|
|
3721
|
+
if (depth === 0) return e + 1;
|
|
3722
|
+
}
|
|
3723
|
+
return str.length;
|
|
3724
|
+
}
|
|
3725
|
+
if (c === "\\") {
|
|
3726
|
+
let q = v;
|
|
3727
|
+
while (q < str.length && str[q] === "\\") q++;
|
|
3728
|
+
if (q < str.length && (str[q] === "\"" || str[q] === "'")) {
|
|
3729
|
+
const level = q - v;
|
|
3730
|
+
let run = 0;
|
|
3731
|
+
for (let e = q + 1; e < str.length; e++) {
|
|
3732
|
+
if (str[e] === "\\") {
|
|
3733
|
+
run++;
|
|
3734
|
+
continue;
|
|
3735
|
+
}
|
|
3736
|
+
if (str[e] === str[q] && run === level) return e + 1;
|
|
3737
|
+
run = 0;
|
|
3738
|
+
}
|
|
3739
|
+
return str.length;
|
|
3740
|
+
}
|
|
3741
|
+
}
|
|
3742
|
+
let e = v;
|
|
3743
|
+
const n = scheme_word_len(str, v);
|
|
3744
|
+
if (n) {
|
|
3745
|
+
e = v + n;
|
|
3746
|
+
while (e < str.length && (str[e] === " " || str[e] === " ")) e++;
|
|
3747
|
+
if (e < str.length && (str[e] === "\"" || str[e] === "'")) return colon_value_end(str, e);
|
|
3748
|
+
}
|
|
3749
|
+
while (e < str.length && COLON_VALUE_STOPS.indexOf(str[e]) < 0) e++;
|
|
3750
|
+
return e;
|
|
3751
|
+
}
|
|
3517
3752
|
var MASK_MAX_NAME = 128;
|
|
3518
3753
|
var MASK_MAX_BYTES = 4194304;
|
|
3519
3754
|
var MASK_TOO_LARGE = "<not shown: too large to mask>";
|
|
3520
|
-
function
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
let m;
|
|
3526
|
-
while ((m = re_attr.exec(str)) !== null) if (is_secret_name(m[2].slice(-128))) value_is_secret = true;
|
|
3527
|
-
let parts = [];
|
|
3528
|
-
let copied = 0;
|
|
3529
|
-
let changed = false;
|
|
3755
|
+
function mark_range(marks, from, to) {
|
|
3756
|
+
for (let i = from; i < to; i++) marks[i] = 1;
|
|
3757
|
+
}
|
|
3758
|
+
function mark_params(str, value_is_secret, as_7_26_9, marks) {
|
|
3759
|
+
const is_blank_or_end = (i) => i >= str.length || str[i] === " " || str[i] === " " || str[i] === "\0";
|
|
3530
3760
|
let outer = "";
|
|
3531
3761
|
let word = 0;
|
|
3532
3762
|
let p = 0;
|
|
3533
|
-
const is_blank_or_end = (i) => i >= str.length || str[i] === " " || str[i] === " ";
|
|
3534
3763
|
while (p < str.length) {
|
|
3535
|
-
|
|
3536
|
-
if (c === " " || c === " ") {
|
|
3764
|
+
const c = str[p];
|
|
3765
|
+
if (c === " " || c === " " || c === "\0") {
|
|
3537
3766
|
p++;
|
|
3538
3767
|
word = p;
|
|
3539
3768
|
continue;
|
|
@@ -3542,43 +3771,124 @@ function mask_secrets_inline(str) {
|
|
|
3542
3771
|
if (!outer && (p === 0 || str[p - 1] === " " || str[p - 1] === " " || str[p - 1] === "=")) outer = c;
|
|
3543
3772
|
else if (c === outer && is_blank_or_end(p + 1)) outer = "";
|
|
3544
3773
|
}
|
|
3774
|
+
if (as_7_26_9) {
|
|
3775
|
+
const [offset, n] = shape_len_7_26_9(str, p);
|
|
3776
|
+
if (n) {
|
|
3777
|
+
p += offset + n;
|
|
3778
|
+
word = p;
|
|
3779
|
+
continue;
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3545
3782
|
if (c !== "=") {
|
|
3546
3783
|
p++;
|
|
3547
3784
|
continue;
|
|
3548
3785
|
}
|
|
3549
|
-
|
|
3786
|
+
const name_from = Math.max(word, p - MASK_MAX_NAME);
|
|
3787
|
+
const name = str.substring(name_from, p);
|
|
3550
3788
|
word = p + 1;
|
|
3551
|
-
if (!(is_secret_name(name) || value_is_secret && name.
|
|
3789
|
+
if (!(is_secret_name(name) || value_is_secret && name.length === 5 && ascii_case_equal(str, name_from, "value"))) {
|
|
3552
3790
|
p++;
|
|
3553
3791
|
continue;
|
|
3554
3792
|
}
|
|
3555
3793
|
p++;
|
|
3556
|
-
let quote = str[p] === "\"" || str[p] === "'" ? str[p] : "";
|
|
3557
3794
|
let end;
|
|
3795
|
+
const quote = p < str.length && (str[p] === "\"" || str[p] === "'") ? str[p] : "";
|
|
3558
3796
|
if (quote) {
|
|
3559
3797
|
end = p + 1;
|
|
3560
|
-
while (end < str.length && str[end] !== quote) end++;
|
|
3561
|
-
if (str[end] === quote) end++;
|
|
3798
|
+
while (end < str.length && str[end] !== quote && str[end] !== "\0") end++;
|
|
3799
|
+
if (end < str.length && str[end] === quote) end++;
|
|
3562
3800
|
} else end = inline_secret_value_end(str, p, outer);
|
|
3563
|
-
|
|
3564
|
-
|
|
3801
|
+
mark_range(marks, p, end);
|
|
3802
|
+
p = end;
|
|
3803
|
+
word = p;
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
function mark_shapes(str, marks) {
|
|
3807
|
+
for (let p = 0; p < str.length; p++) {
|
|
3808
|
+
const c = str[p];
|
|
3809
|
+
if (c !== "e" && c !== "b" && c !== "B") continue;
|
|
3810
|
+
const [offset, n] = shape_len(str, p);
|
|
3811
|
+
if (n) mark_range(marks, p + offset, p + offset + n);
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
function mark_labels(str, marks) {
|
|
3815
|
+
let word = 0;
|
|
3816
|
+
let p = 0;
|
|
3817
|
+
while (p < str.length) {
|
|
3818
|
+
const c = str[p];
|
|
3819
|
+
if (c === " " || c === " " || c === "\0" || c === "=") {
|
|
3820
|
+
p++;
|
|
3821
|
+
word = p;
|
|
3822
|
+
continue;
|
|
3823
|
+
}
|
|
3824
|
+
if (c !== ":") {
|
|
3825
|
+
p++;
|
|
3826
|
+
continue;
|
|
3827
|
+
}
|
|
3828
|
+
if (!is_secret_name(str.substring(Math.max(word, p - MASK_MAX_NAME), p))) {
|
|
3829
|
+
p++;
|
|
3830
|
+
word = p;
|
|
3831
|
+
continue;
|
|
3832
|
+
}
|
|
3833
|
+
let v = p + 1;
|
|
3834
|
+
while (v < str.length && (str[v] === " " || str[v] === " ")) v++;
|
|
3835
|
+
const e = colon_value_end(str, v);
|
|
3836
|
+
mark_range(marks, v, e);
|
|
3837
|
+
const n_scheme = scheme_word_len(str, v);
|
|
3838
|
+
if (n_scheme) p = v + n_scheme;
|
|
3839
|
+
else p = e > v ? e : p + 1;
|
|
3840
|
+
word = p;
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
/************************************************************
|
|
3844
|
+
* A text (a command line) with the secrets that can be told
|
|
3845
|
+
* written as "********" (each run of them as one), the rest as it
|
|
3846
|
+
* is: the value of every "name=value" whose name is a secret's,
|
|
3847
|
+
* quoted or not (and the "value" of a write-attr whose attribute
|
|
3848
|
+
* names a secret); the same for a "name: value", its name in quotes
|
|
3849
|
+
* or not (a json, a header, a label: "password": x, Authorization:
|
|
3850
|
+
* Basic x, bearer: tok); and a JWT or the credential after "Bearer "
|
|
3851
|
+
* or "Basic ", wherever they are, whatever names them. Each rule
|
|
3852
|
+
* judges the text as it came. Return null when there was nothing to
|
|
3853
|
+
* mask. As the C kernel's mask_secrets_inline().
|
|
3854
|
+
************************************************************/
|
|
3855
|
+
function mask_secrets_inline(str) {
|
|
3856
|
+
if (typeof str !== "string") return null;
|
|
3857
|
+
if (str.indexOf("=") < 0 && str.indexOf(":") < 0 && str.indexOf("eyJ") < 0 && !/bearer|basic/i.test(str)) return null;
|
|
3858
|
+
if (str.length > MASK_MAX_BYTES) return MASK_TOO_LARGE;
|
|
3859
|
+
let value_is_secret = false;
|
|
3860
|
+
let re_attr = /(^|[ \t])attribute=["']?([^ \t"'\u0000]*)/g;
|
|
3861
|
+
let m;
|
|
3862
|
+
while ((m = re_attr.exec(str)) !== null) if (is_secret_name(m[2].slice(-128))) value_is_secret = true;
|
|
3863
|
+
const marks = new Uint8Array(str.length);
|
|
3864
|
+
mark_params(str, value_is_secret, true, marks);
|
|
3865
|
+
mark_params(str, value_is_secret, false, marks);
|
|
3866
|
+
mark_shapes(str, marks);
|
|
3867
|
+
mark_labels(str, marks);
|
|
3868
|
+
let parts = [];
|
|
3869
|
+
let changed = false;
|
|
3870
|
+
let i = 0;
|
|
3871
|
+
while (i < str.length) {
|
|
3872
|
+
let j = i;
|
|
3873
|
+
if (marks[i]) {
|
|
3874
|
+
while (j < str.length && marks[j]) j++;
|
|
3565
3875
|
parts.push("********");
|
|
3566
|
-
copied = end;
|
|
3567
3876
|
changed = true;
|
|
3877
|
+
} else {
|
|
3878
|
+
while (j < str.length && !marks[j]) j++;
|
|
3879
|
+
parts.push(str.substring(i, j));
|
|
3568
3880
|
}
|
|
3569
|
-
|
|
3570
|
-
word = p;
|
|
3881
|
+
i = j;
|
|
3571
3882
|
}
|
|
3572
|
-
|
|
3573
|
-
parts.push(str.substring(copied));
|
|
3574
|
-
return parts.join("");
|
|
3883
|
+
return changed ? parts.join("") : null;
|
|
3575
3884
|
}
|
|
3576
3885
|
/************************************************************
|
|
3577
3886
|
* A json as a log or a trace may show it: at any depth, the
|
|
3578
3887
|
* value of a key with a secret's name is "********", whatever
|
|
3579
3888
|
* its type (not an absent one, a null or an empty string); so is
|
|
3580
3889
|
* the "value" of a dict whose "attribute" names a secret; and a
|
|
3581
|
-
* string is masked as mask_secrets_inline()
|
|
3890
|
+
* string, under any key, is masked as mask_secrets_inline() (a
|
|
3891
|
+
* JWT, a "Bearer" token, a secret name=value). Return a masked
|
|
3582
3892
|
* copy, or `jn` itself when there was nothing to mask. As the C
|
|
3583
3893
|
* kernel's json_mask_secrets().
|
|
3584
3894
|
*
|
|
@@ -3607,7 +3917,7 @@ function _json_mask_secrets(jn, memo, depth, budget) {
|
|
|
3607
3917
|
return MASK_TOO_LARGE;
|
|
3608
3918
|
}
|
|
3609
3919
|
budget.left -= jn.length;
|
|
3610
|
-
let masked = mask_secrets_inline(jn);
|
|
3920
|
+
let masked = mask_secrets_inline(jn.indexOf("\0") >= 0 ? jn.replace(/\u0000/g, " ") : jn);
|
|
3611
3921
|
return masked !== null ? masked : jn;
|
|
3612
3922
|
}
|
|
3613
3923
|
let is_array = Array.isArray(jn);
|
|
@@ -7109,15 +7419,34 @@ function save_trace_scope(gobj, attr, scope, levels) {
|
|
|
7109
7419
|
return gobj_save_persistent_attrs(gobj, attr);
|
|
7110
7420
|
}
|
|
7111
7421
|
/***************************************************************
|
|
7112
|
-
* "set" as the C command reads it
|
|
7422
|
+
* "set" as the C command reads it (trace_set_value() of c_yuno.c):
|
|
7423
|
+
* a boolean; an integer in the range of an int (true unless 0); or
|
|
7424
|
+
* text -- set / reset, a JSON integer -?(0|[1-9][0-9]*), or true /
|
|
7425
|
+
* false, yes / no, on / off, any case. null for anything else: a
|
|
7426
|
+
* real (2.5), " 1", "0x1", "1e3", "+5", "007" and "2.5" are refused,
|
|
7427
|
+
* as in C. Up to gobj-js 7.26.19 the text went through Number(),
|
|
7428
|
+
* which took all of them, and "yes" / "on" were refused.
|
|
7113
7429
|
***************************************************************/
|
|
7430
|
+
var INT_MIN = -2147483648;
|
|
7431
|
+
var INT_MAX = 2147483647;
|
|
7114
7432
|
function parse_set(value) {
|
|
7115
7433
|
if (value === true || value === false) return value;
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7434
|
+
if (typeof value === "number") {
|
|
7435
|
+
if (!Number.isInteger(value) || value < INT_MIN || value > INT_MAX) return null;
|
|
7436
|
+
return value !== 0;
|
|
7437
|
+
}
|
|
7438
|
+
if (typeof value !== "string" || value === "") return null;
|
|
7439
|
+
let v = value.toLowerCase();
|
|
7440
|
+
if (v === "set") return true;
|
|
7441
|
+
if (v === "reset") return false;
|
|
7442
|
+
if (/^-?(0|[1-9][0-9]*)$/.test(value)) {
|
|
7443
|
+
let n = Number(value);
|
|
7444
|
+
if (n < INT_MIN || n > INT_MAX) return null;
|
|
7445
|
+
return n !== 0;
|
|
7446
|
+
}
|
|
7447
|
+
if (v === "true" || v === "yes" || v === "on") return true;
|
|
7448
|
+
if (v === "false" || v === "no" || v === "off") return false;
|
|
7449
|
+
return null;
|
|
7121
7450
|
}
|
|
7122
7451
|
function yuno_prefix() {
|
|
7123
7452
|
return `${gobj_yuno_role()}^${gobj_yuno_name()}`;
|