@yuneta/gobj-js 7.26.23 → 7.26.25
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 +72 -3
- package/dist/gobj-js.cjs.js +424 -71
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +2095 -1867
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +424 -72
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +1837 -1609
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +424 -71
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +2215 -1987
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +424 -71
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +2215 -1987
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/gobj-js.cjs.js
CHANGED
|
@@ -866,6 +866,112 @@ var JSON_NUMBER_TEXT = /^-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?$/;
|
|
|
866
866
|
var INT64_MIN = -(2n ** 63n);
|
|
867
867
|
var INT64_MAX = 2n ** 63n - 1n;
|
|
868
868
|
var REFUSED_TEXT = "a text that does not read as one";
|
|
869
|
+
var JSON_NUMBER_TOKEN = /-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/y;
|
|
870
|
+
function is_surrogate_pair(high, low) {
|
|
871
|
+
return high >= 55296 && high <= 56319 && low >= 56320 && low <= 57343;
|
|
872
|
+
}
|
|
873
|
+
var JSON_MAX_DEPTH = 2048;
|
|
874
|
+
function json_text_refused_by_c(s) {
|
|
875
|
+
const n = s.length;
|
|
876
|
+
let i = 0;
|
|
877
|
+
let depth = 0;
|
|
878
|
+
const in_object = [];
|
|
879
|
+
let key_next = false;
|
|
880
|
+
while (i < n) {
|
|
881
|
+
const c = s.charCodeAt(i);
|
|
882
|
+
if (c === 123 || c === 91) {
|
|
883
|
+
depth++;
|
|
884
|
+
if (depth > JSON_MAX_DEPTH) return true;
|
|
885
|
+
in_object.push(c === 123);
|
|
886
|
+
key_next = c === 123;
|
|
887
|
+
i++;
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
if (c === 125 || c === 93) {
|
|
891
|
+
depth--;
|
|
892
|
+
in_object.pop();
|
|
893
|
+
key_next = false;
|
|
894
|
+
i++;
|
|
895
|
+
continue;
|
|
896
|
+
}
|
|
897
|
+
if (c === 44) {
|
|
898
|
+
key_next = in_object.length > 0 && in_object[in_object.length - 1];
|
|
899
|
+
i++;
|
|
900
|
+
continue;
|
|
901
|
+
}
|
|
902
|
+
if (c === 58) {
|
|
903
|
+
key_next = false;
|
|
904
|
+
i++;
|
|
905
|
+
continue;
|
|
906
|
+
}
|
|
907
|
+
if (c === 116 || c === 102 || c === 110) {
|
|
908
|
+
if (depth + 1 > JSON_MAX_DEPTH) return true;
|
|
909
|
+
i += c === 102 ? 5 : 4;
|
|
910
|
+
continue;
|
|
911
|
+
}
|
|
912
|
+
if (c === 34) {
|
|
913
|
+
if (!key_next && depth + 1 > JSON_MAX_DEPTH) return true;
|
|
914
|
+
key_next = false;
|
|
915
|
+
i++;
|
|
916
|
+
while (i < n) {
|
|
917
|
+
const d = s.charCodeAt(i);
|
|
918
|
+
if (d === 34) {
|
|
919
|
+
i++;
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
if (d === 92 && s[i + 1] === "u") {
|
|
923
|
+
const u = parseInt(s.substring(i + 2, i + 6), 16);
|
|
924
|
+
if (u === 0) return true;
|
|
925
|
+
if (u >= 55296 && u <= 57343) {
|
|
926
|
+
if (!is_surrogate_pair(u, s[i + 6] === "\\" && s[i + 7] === "u" ? parseInt(s.substring(i + 8, i + 12), 16) : -1)) return true;
|
|
927
|
+
i += 12;
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
i += 6;
|
|
931
|
+
continue;
|
|
932
|
+
}
|
|
933
|
+
if (d === 92) {
|
|
934
|
+
i += 2;
|
|
935
|
+
continue;
|
|
936
|
+
}
|
|
937
|
+
if (d >= 55296 && d <= 57343) {
|
|
938
|
+
if (!is_surrogate_pair(d, s.charCodeAt(i + 1))) return true;
|
|
939
|
+
i += 2;
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
i++;
|
|
943
|
+
}
|
|
944
|
+
continue;
|
|
945
|
+
}
|
|
946
|
+
if (c === 45 || c >= 48 && c <= 57) {
|
|
947
|
+
if (depth + 1 > JSON_MAX_DEPTH) return true;
|
|
948
|
+
JSON_NUMBER_TOKEN.lastIndex = i;
|
|
949
|
+
const m = JSON_NUMBER_TOKEN.exec(s);
|
|
950
|
+
if (!m) return true;
|
|
951
|
+
const token = m[0];
|
|
952
|
+
if (/[.eE]/.test(token)) {
|
|
953
|
+
if (!Number.isFinite(Number(token))) return true;
|
|
954
|
+
} else {
|
|
955
|
+
const big = BigInt(token);
|
|
956
|
+
if (big < INT64_MIN || big > INT64_MAX) return true;
|
|
957
|
+
}
|
|
958
|
+
i += token.length;
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
i++;
|
|
962
|
+
}
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
function parse_json_text_as_c(s) {
|
|
966
|
+
let jn;
|
|
967
|
+
try {
|
|
968
|
+
jn = JSON.parse(s);
|
|
969
|
+
} catch (e) {
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
if (json_text_refused_by_c(s)) return;
|
|
973
|
+
return jn;
|
|
974
|
+
}
|
|
869
975
|
function value_has_shape(type, value) {
|
|
870
976
|
if (DTP_IS_STRING(type)) return is_string(value);
|
|
871
977
|
if (DTP_IS_DICT(type)) return is_object(value);
|
|
@@ -877,7 +983,7 @@ function shape_of_value(value) {
|
|
|
877
983
|
if (is_array(value)) return "an array";
|
|
878
984
|
if (is_object(value)) return "an object";
|
|
879
985
|
if (is_string(value)) return REFUSED_TEXT;
|
|
880
|
-
if (typeof value === "number") return Number.isInteger(value) ? "an integer" : "a real";
|
|
986
|
+
if (typeof value === "number") return Number.isInteger(value) && Math.abs(value) <= 0x8000000000000000 ? "an integer" : "a real";
|
|
881
987
|
if (typeof value === "boolean") return "a boolean";
|
|
882
988
|
return "null";
|
|
883
989
|
}
|
|
@@ -898,7 +1004,7 @@ function number_as_type(type, value) {
|
|
|
898
1004
|
value: value ? 1 : 0,
|
|
899
1005
|
refused: null
|
|
900
1006
|
};
|
|
901
|
-
if (!(value >= -0x8000000000000000 && value
|
|
1007
|
+
if (!(value >= -0x8000000000000000 && value <= 0x8000000000000000)) return {
|
|
902
1008
|
value: void 0,
|
|
903
1009
|
refused: "a number out of its range"
|
|
904
1010
|
};
|
|
@@ -969,16 +1075,8 @@ function text2parameter(type, s, from_kw) {
|
|
|
969
1075
|
};
|
|
970
1076
|
}
|
|
971
1077
|
if (DTP_IS_DICT(type) || DTP_IS_LIST(type)) {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
jn = JSON.parse(s);
|
|
975
|
-
} catch (e) {
|
|
976
|
-
return {
|
|
977
|
-
value: void 0,
|
|
978
|
-
refused: REFUSED_TEXT
|
|
979
|
-
};
|
|
980
|
-
}
|
|
981
|
-
if (!value_has_shape(type, jn)) return {
|
|
1078
|
+
const jn = parse_json_text_as_c(s);
|
|
1079
|
+
if (jn === void 0 || !value_has_shape(type, jn)) return {
|
|
982
1080
|
value: void 0,
|
|
983
1081
|
refused: REFUSED_TEXT
|
|
984
1082
|
};
|
|
@@ -987,12 +1085,12 @@ function text2parameter(type, s, from_kw) {
|
|
|
987
1085
|
refused: null
|
|
988
1086
|
};
|
|
989
1087
|
}
|
|
990
|
-
if (DTP_IS_JSON(type))
|
|
991
|
-
|
|
992
|
-
|
|
1088
|
+
if (DTP_IS_JSON(type)) {
|
|
1089
|
+
const jn = parse_json_text_as_c(s);
|
|
1090
|
+
if (jn !== void 0) return {
|
|
1091
|
+
value: jn,
|
|
993
1092
|
refused: null
|
|
994
1093
|
};
|
|
995
|
-
} catch (e) {
|
|
996
1094
|
const t = s.replace(/^[ \t]+/, "");
|
|
997
1095
|
if (t.startsWith("{") || t.startsWith("[") || t.startsWith("\"")) return {
|
|
998
1096
|
value: void 0,
|
|
@@ -1067,6 +1165,10 @@ function command_parameter_from_json(type, value) {
|
|
|
1067
1165
|
refused: shape_of_value(value)
|
|
1068
1166
|
};
|
|
1069
1167
|
if (DTP_IS_NUMBER(type)) return number_as_type(type, value);
|
|
1168
|
+
if (!is_json_value(value)) return {
|
|
1169
|
+
value: void 0,
|
|
1170
|
+
refused: NO_JSON_TEXT
|
|
1171
|
+
};
|
|
1070
1172
|
return {
|
|
1071
1173
|
value,
|
|
1072
1174
|
refused: null
|
|
@@ -1085,8 +1187,44 @@ var TYPES_READ = [
|
|
|
1085
1187
|
data_type_t.DTP_LIST,
|
|
1086
1188
|
data_type_t.DTP_DICT
|
|
1087
1189
|
];
|
|
1190
|
+
var LEAVE_NODE = Symbol("leave");
|
|
1191
|
+
function is_json_value(value) {
|
|
1192
|
+
const on_path = /* @__PURE__ */ new Set();
|
|
1193
|
+
const stack = [value];
|
|
1194
|
+
while (stack.length) {
|
|
1195
|
+
const v = stack.pop();
|
|
1196
|
+
if (v === LEAVE_NODE) {
|
|
1197
|
+
on_path.delete(stack.pop());
|
|
1198
|
+
continue;
|
|
1199
|
+
}
|
|
1200
|
+
if (typeof v === "bigint") return false;
|
|
1201
|
+
if (v === null || typeof v !== "object") continue;
|
|
1202
|
+
if (on_path.has(v)) return false;
|
|
1203
|
+
const array = Array.isArray(v);
|
|
1204
|
+
if (!array) {
|
|
1205
|
+
const proto = Object.getPrototypeOf(v);
|
|
1206
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
1207
|
+
}
|
|
1208
|
+
on_path.add(v);
|
|
1209
|
+
stack.push(v, LEAVE_NODE);
|
|
1210
|
+
if (array) for (let i = 0; i < v.length; i++) stack.push(v[i]);
|
|
1211
|
+
else for (const key of Object.keys(v)) stack.push(v[key]);
|
|
1212
|
+
}
|
|
1213
|
+
return true;
|
|
1214
|
+
}
|
|
1215
|
+
var NO_JSON_TEXT = "a value with no json text";
|
|
1216
|
+
function json_text_of(value) {
|
|
1217
|
+
if (!is_json_value(value)) return;
|
|
1218
|
+
try {
|
|
1219
|
+
const s = JSON.stringify(value);
|
|
1220
|
+
return is_string(s) ? s : void 0;
|
|
1221
|
+
} catch (e) {
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1088
1225
|
function log_attr_value_refused(gobj, it, value, refused) {
|
|
1089
1226
|
const types = {
|
|
1227
|
+
[data_type_t.DTP_STRING]: "a string",
|
|
1090
1228
|
[data_type_t.DTP_BOOLEAN]: "a boolean",
|
|
1091
1229
|
[data_type_t.DTP_INTEGER]: "an integer",
|
|
1092
1230
|
[data_type_t.DTP_REAL]: "a real",
|
|
@@ -1096,7 +1234,8 @@ function log_attr_value_refused(gobj, it, value, refused) {
|
|
|
1096
1234
|
let shown;
|
|
1097
1235
|
if (it.flag & sdata_flag_t.SDF_SECRET) shown = "********";
|
|
1098
1236
|
else {
|
|
1099
|
-
shown = is_string(value) ? value :
|
|
1237
|
+
shown = is_string(value) ? value : json_text_of(value === void 0 ? null : value);
|
|
1238
|
+
if (shown === void 0) shown = `<${NO_JSON_TEXT}>`;
|
|
1100
1239
|
const masked = mask_secrets_inline(shown);
|
|
1101
1240
|
if (masked !== null) shown = masked;
|
|
1102
1241
|
if (shown.length > ATTR_VALUE_SHOWN) {
|
|
@@ -1118,8 +1257,11 @@ function json2item(gobj, sdata, it, jn_value_) {
|
|
|
1118
1257
|
if (jn_value_ === null || jn_value_ === void 0) jn_value2 = "";
|
|
1119
1258
|
else if (is_string(jn_value_)) jn_value2 = String(jn_value_);
|
|
1120
1259
|
else {
|
|
1121
|
-
|
|
1122
|
-
if (
|
|
1260
|
+
jn_value2 = json_text_of(jn_value_);
|
|
1261
|
+
if (jn_value2 === void 0) {
|
|
1262
|
+
log_attr_value_refused(gobj, it, jn_value_, NO_JSON_TEXT);
|
|
1263
|
+
return -1;
|
|
1264
|
+
}
|
|
1123
1265
|
}
|
|
1124
1266
|
break;
|
|
1125
1267
|
case data_type_t.DTP_BOOLEAN:
|
|
@@ -2567,15 +2709,20 @@ function write_attr_value(gobj, key, value) {
|
|
|
2567
2709
|
* The value a typed writer writes, read as ITS type by the grammar of
|
|
2568
2710
|
* json2item() (a C writer takes its C type: a string is never read as a
|
|
2569
2711
|
* number there). Return {value} or {refused} (logged): the attr keeps its
|
|
2570
|
-
* value. A string writer
|
|
2571
|
-
*
|
|
2712
|
+
* value. A string writer takes null and undefined as "", any other json
|
|
2713
|
+
* as its text, as a DTP_STRING attr reads them; it refuses only a value
|
|
2714
|
+
* with no json text (circular, a BigInt).
|
|
2572
2715
|
***************************************************************************/
|
|
2573
2716
|
function typed_writer_value(gobj, name, type, value) {
|
|
2717
|
+
let r;
|
|
2574
2718
|
if (DTP_IS_STRING(type)) {
|
|
2575
2719
|
if (value === null || value === void 0) return { value: "" };
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2720
|
+
if (is_string(value)) return { value };
|
|
2721
|
+
r = {
|
|
2722
|
+
value: json_text_of(value),
|
|
2723
|
+
refused: NO_JSON_TEXT
|
|
2724
|
+
};
|
|
2725
|
+
} else r = command_parameter_from_json(type, value);
|
|
2579
2726
|
if (r.value === void 0) {
|
|
2580
2727
|
let holder = gobj;
|
|
2581
2728
|
while (holder && !gobj_has_attr(holder, name)) holder = holder.bottom_gobj;
|
|
@@ -3020,9 +3167,9 @@ function gobj_send_event(dst, event, kw, src) {
|
|
|
3020
3167
|
}
|
|
3021
3168
|
}
|
|
3022
3169
|
const frame = push_dispatch_frame(dst, event, frame_kind_t.FRAME_ACTION);
|
|
3023
|
-
if (event_action.next_state) gobj_change_state(dst, event_action.next_state);
|
|
3024
3170
|
let ret = -1;
|
|
3025
3171
|
try {
|
|
3172
|
+
if (event_action.next_state) gobj_change_state(dst, event_action.next_state);
|
|
3026
3173
|
if (event_action.action) ret = event_action.action(dst, event, kw, src);
|
|
3027
3174
|
} catch (e) {
|
|
3028
3175
|
__inside__--;
|
|
@@ -3046,18 +3193,23 @@ var subs_flag_t = Object.freeze({
|
|
|
3046
3193
|
__own_event__: 4
|
|
3047
3194
|
});
|
|
3048
3195
|
/***************************************************************************
|
|
3049
|
-
* The event type of `event_name` in any registered gclass
|
|
3050
|
-
*
|
|
3196
|
+
* The event type of `event_name` in any registered gclass whose flags
|
|
3197
|
+
* hold one of `event_flag` (0: any), null if none. The C kernel's
|
|
3198
|
+
* gobj_find_event_type(): any case, gclasses only. With `verbose` a miss
|
|
3199
|
+
* is logged, with the name as it was given: never verbose for a name
|
|
3200
|
+
* that came from a peer.
|
|
3051
3201
|
***************************************************************************/
|
|
3052
|
-
function
|
|
3202
|
+
function gobj_find_event_type(event_name, event_flag, verbose) {
|
|
3053
3203
|
let lower = String(event_name).toLowerCase();
|
|
3054
3204
|
for (let gclass_name in _gclass_register) {
|
|
3055
3205
|
let dl = _gclass_register[gclass_name].dl_events;
|
|
3056
3206
|
for (let i = 0; i < dl.length; i++) {
|
|
3057
3207
|
let event_type = dl[i];
|
|
3208
|
+
if (event_flag && !(event_type.event_flag & event_flag)) continue;
|
|
3058
3209
|
if (event_type.event_name && event_type.event_name.toLowerCase() === lower) return event_type;
|
|
3059
3210
|
}
|
|
3060
3211
|
}
|
|
3212
|
+
if (verbose) log_error(`EVENT NOT FOUND: ${event_name}`);
|
|
3061
3213
|
return null;
|
|
3062
3214
|
}
|
|
3063
3215
|
var subscription_desc = [
|
|
@@ -3094,7 +3246,7 @@ function _create_subscription(publisher, event, kw, subscriber) {
|
|
|
3094
3246
|
json_object_set_new(subs, "__config__", kw_clone);
|
|
3095
3247
|
let renamed_event = kw_get_str(publisher, kw_clone, "__rename_event_name__", "");
|
|
3096
3248
|
if (!empty_string(renamed_event)) {
|
|
3097
|
-
let event_type =
|
|
3249
|
+
let event_type = gobj_find_event_type(renamed_event, 0, false);
|
|
3098
3250
|
if (event_type) {
|
|
3099
3251
|
json_object_set_new(subs, "renamed_event", event_type.event_name);
|
|
3100
3252
|
delete kw_clone.__rename_event_name__;
|
|
@@ -3155,7 +3307,7 @@ function _subscription_match_kw(kw, event) {
|
|
|
3155
3307
|
kw_match.__config__ = config_match;
|
|
3156
3308
|
let renamed_event = "";
|
|
3157
3309
|
let rename = config_match.__rename_event_name__;
|
|
3158
|
-
let event_type = typeof rename === "string" && !empty_string(rename) ?
|
|
3310
|
+
let event_type = typeof rename === "string" && !empty_string(rename) ? gobj_find_event_type(rename, 0, false) : null;
|
|
3159
3311
|
if (event_type) {
|
|
3160
3312
|
renamed_event = event_type.event_name;
|
|
3161
3313
|
delete config_match.__rename_event_name__;
|
|
@@ -4021,6 +4173,35 @@ function is_secret_name_tail(str, from, to, names) {
|
|
|
4021
4173
|
}
|
|
4022
4174
|
return secret_name_check(str, i, to, true, by_segments);
|
|
4023
4175
|
}
|
|
4176
|
+
function param_name_tail_from(str, from, to) {
|
|
4177
|
+
let bytes = 0;
|
|
4178
|
+
let i = to;
|
|
4179
|
+
while (i > from) {
|
|
4180
|
+
const code = str.charCodeAt(i - 1);
|
|
4181
|
+
let n = 3;
|
|
4182
|
+
let units = 1;
|
|
4183
|
+
if (code < 128) n = 1;
|
|
4184
|
+
else if (code < 2048) n = 2;
|
|
4185
|
+
else if (code >= 56320 && code <= 57343 && i - 2 >= from) {
|
|
4186
|
+
const high = str.charCodeAt(i - 2);
|
|
4187
|
+
if (high >= 55296 && high <= 56319) {
|
|
4188
|
+
n = 4;
|
|
4189
|
+
units = 2;
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4192
|
+
if (bytes + n > MASK_MAX_NAME) return -1;
|
|
4193
|
+
if (code === 38 || code === 63 || code === 59) return i;
|
|
4194
|
+
bytes += n;
|
|
4195
|
+
i -= units;
|
|
4196
|
+
}
|
|
4197
|
+
return -1;
|
|
4198
|
+
}
|
|
4199
|
+
function is_param_name_secret(str, from, to, names) {
|
|
4200
|
+
const tail = names === NAMES_NOW ? param_name_tail_from(str, from, to) : -1;
|
|
4201
|
+
if (tail < 0) return is_secret_name_tail(str, from, to, names);
|
|
4202
|
+
if (is_secret_name_tail(str, from, to, NAMES_7_26_9)) return true;
|
|
4203
|
+
return is_secret_name_tail(str, from, to, NAMES_NOW) && secret_name_check(str, tail, to, false, true);
|
|
4204
|
+
}
|
|
4024
4205
|
/************************************************************
|
|
4025
4206
|
* Where an unquoted secret value that begins at `p` ends: at
|
|
4026
4207
|
* the end, at the quote that closes an outer quoted value, or
|
|
@@ -4318,13 +4499,14 @@ function mark_params(str, value_is_secret, reading, marks, judged) {
|
|
|
4318
4499
|
}
|
|
4319
4500
|
const name_from = word;
|
|
4320
4501
|
word = p + 1;
|
|
4321
|
-
const secret =
|
|
4322
|
-
if (secret && names === NAMES_NOW && !is_secret_name_tail(str, name_from, p, NAMES_7_26_9)) not_7_26_9 = true;
|
|
4502
|
+
const secret = is_param_name_secret(str, name_from, p, names);
|
|
4503
|
+
if (secret && names === NAMES_NOW && !not_7_26_9 && !is_secret_name_tail(str, name_from, p, NAMES_7_26_9)) not_7_26_9 = true;
|
|
4323
4504
|
if (!(secret || value_is_secret && p - name_from === 5 && ascii_case_equal(str, name_from, "value"))) {
|
|
4324
|
-
if (judged && query_name_from(str, p) === name_from) judged[p] =
|
|
4505
|
+
if (judged && query_name_from(str, p) === name_from) judged[p] = JUDGED_NOT_SECRET;
|
|
4325
4506
|
p++;
|
|
4326
4507
|
continue;
|
|
4327
4508
|
}
|
|
4509
|
+
if (judged && secret && query_name_from(str, p) === name_from) judged[p] = JUDGED_SECRET;
|
|
4328
4510
|
p++;
|
|
4329
4511
|
let end;
|
|
4330
4512
|
const quote = p < str.length && (str[p] === "\"" || str[p] === "'") ? str[p] : "";
|
|
@@ -4387,23 +4569,99 @@ function query_name_from(str, eq) {
|
|
|
4387
4569
|
while (n > 0 && eq - n < MASK_MAX_NAME && is_name_char_code(str.charCodeAt(n - 1))) n--;
|
|
4388
4570
|
return n;
|
|
4389
4571
|
}
|
|
4572
|
+
var JUDGED_NOT_SECRET = 1;
|
|
4573
|
+
var JUDGED_SECRET = 2;
|
|
4574
|
+
function hex_digit_value(code) {
|
|
4575
|
+
if (code >= 48 && code <= 57) return code - 48;
|
|
4576
|
+
if (code >= 97 && code <= 102) return code - 87;
|
|
4577
|
+
if (code >= 65 && code <= 70) return code - 55;
|
|
4578
|
+
return -1;
|
|
4579
|
+
}
|
|
4580
|
+
function is_written_name_bracket_code(code) {
|
|
4581
|
+
return code === 91 || code === 93 || code === 39 || code === 34;
|
|
4582
|
+
}
|
|
4583
|
+
function is_written_name_code(code) {
|
|
4584
|
+
return is_name_char_code(code) || code === 37 || is_written_name_bracket_code(code);
|
|
4585
|
+
}
|
|
4586
|
+
function written_name_is_secret(str, eq) {
|
|
4587
|
+
let n = eq;
|
|
4588
|
+
let plain = -1;
|
|
4589
|
+
while (n > 0 && eq - n < MASK_MAX_NAME && is_written_name_code(str.charCodeAt(n - 1))) {
|
|
4590
|
+
n--;
|
|
4591
|
+
if (plain < 0 && !is_name_char_code(str.charCodeAt(n))) plain = n + 1;
|
|
4592
|
+
}
|
|
4593
|
+
if (plain < 0) return false;
|
|
4594
|
+
const to = str.charCodeAt(plain - 1) === 37 ? eq : plain - 1;
|
|
4595
|
+
let encoded = false;
|
|
4596
|
+
for (let s = n; s < to && !encoded; s++) encoded = str.charCodeAt(s) === 37;
|
|
4597
|
+
let name = str;
|
|
4598
|
+
let from = n;
|
|
4599
|
+
let end = to;
|
|
4600
|
+
if (encoded) {
|
|
4601
|
+
name = "";
|
|
4602
|
+
for (let s = n; s < to; s++) {
|
|
4603
|
+
const hi = str.charCodeAt(s) === 37 && to - s > 2 ? hex_digit_value(str.charCodeAt(s + 1)) : -1;
|
|
4604
|
+
const lo = hi >= 0 ? hex_digit_value(str.charCodeAt(s + 2)) : -1;
|
|
4605
|
+
if (lo >= 0) {
|
|
4606
|
+
name += String.fromCharCode(hi * 16 + lo);
|
|
4607
|
+
s += 2;
|
|
4608
|
+
} else name += str[s];
|
|
4609
|
+
}
|
|
4610
|
+
from = 0;
|
|
4611
|
+
end = name.length;
|
|
4612
|
+
}
|
|
4613
|
+
let seg = from;
|
|
4614
|
+
for (let i = from; i <= end; i++) {
|
|
4615
|
+
if (i < end && !is_written_name_bracket_code(name.charCodeAt(i))) continue;
|
|
4616
|
+
if (i - seg >= 3 && secret_name_check(name, seg, i, true, true)) return true;
|
|
4617
|
+
seg = i + 1;
|
|
4618
|
+
}
|
|
4619
|
+
return false;
|
|
4620
|
+
}
|
|
4621
|
+
function mark_query_value(str, eq, marks) {
|
|
4622
|
+
const v = eq + 1;
|
|
4623
|
+
if (v < str.length && (str[v] === "\"" || str[v] === "'")) return mark_run(str, v + 1, QUOTE_STOPS[str[v]], marks);
|
|
4624
|
+
mark_scheme_value(str, v, PARAM_VALUE_STOPS, marks);
|
|
4625
|
+
return mark_run(str, v, PARAM_VALUE_STOPS, marks);
|
|
4626
|
+
}
|
|
4627
|
+
var WRITTEN_NAME_MARKS = /[[\]%'"]/;
|
|
4390
4628
|
function mark_query_params(str, marks, judged) {
|
|
4391
4629
|
let frontier = 0;
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4630
|
+
let frontier_written = WRITTEN_NAME_MARKS.test(str) ? 0 : str.length;
|
|
4631
|
+
let p = str.indexOf("=", 1);
|
|
4632
|
+
while (p > 0) {
|
|
4633
|
+
if (p >= frontier) {
|
|
4634
|
+
let secret = judged[p] === JUDGED_SECRET;
|
|
4635
|
+
if (!judged[p]) {
|
|
4636
|
+
const n = query_name_from(str, p);
|
|
4637
|
+
secret = n < p && secret_name_check(str, n, p, true, true);
|
|
4638
|
+
}
|
|
4639
|
+
if (secret) frontier = mark_query_value(str, p, marks);
|
|
4640
|
+
}
|
|
4641
|
+
if (p >= frontier_written && written_name_is_secret(str, p)) frontier_written = mark_query_value(str, p, marks);
|
|
4642
|
+
p = str.indexOf("=", p + 1);
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4645
|
+
var URL_AUTHORITY_STOPS = stop_table("/?#\"'<> ");
|
|
4646
|
+
function mark_url_passwords(str, marks) {
|
|
4647
|
+
let p = str.indexOf("://", 1);
|
|
4648
|
+
while (p > 0) {
|
|
4649
|
+
let next = p + 1;
|
|
4650
|
+
if (is_ascii_alnum_code(str.charCodeAt(p - 1))) {
|
|
4651
|
+
let colon = -1;
|
|
4652
|
+
let at = -1;
|
|
4653
|
+
let e = p + 3;
|
|
4654
|
+
while (e < str.length) {
|
|
4655
|
+
const code = str.charCodeAt(e);
|
|
4656
|
+
if (code < 128 && URL_AUTHORITY_STOPS[code]) break;
|
|
4657
|
+
if (code === 64) at = e;
|
|
4658
|
+
else if (code === 58 && colon < 0) colon = e;
|
|
4659
|
+
e++;
|
|
4660
|
+
}
|
|
4661
|
+
if (colon >= 0 && at > colon) mark_range(marks, colon + 1, at);
|
|
4662
|
+
next = e - 1;
|
|
4406
4663
|
}
|
|
4664
|
+
p = str.indexOf("://", next);
|
|
4407
4665
|
}
|
|
4408
4666
|
}
|
|
4409
4667
|
function mark_shapes(str, marks) {
|
|
@@ -4428,7 +4686,7 @@ function mark_labels(str, marks) {
|
|
|
4428
4686
|
p++;
|
|
4429
4687
|
continue;
|
|
4430
4688
|
}
|
|
4431
|
-
if (!
|
|
4689
|
+
if (!is_param_name_secret(str, word, p, NAMES_NOW)) {
|
|
4432
4690
|
p++;
|
|
4433
4691
|
word = p;
|
|
4434
4692
|
continue;
|
|
@@ -4457,6 +4715,50 @@ function inline_value_is_secret(str, names) {
|
|
|
4457
4715
|
}
|
|
4458
4716
|
return false;
|
|
4459
4717
|
}
|
|
4718
|
+
function mark_inline_rules_of_now(str, marks) {
|
|
4719
|
+
const value_is_secret = inline_value_is_secret(str, NAMES_NOW);
|
|
4720
|
+
const judged = new Uint8Array(str.length);
|
|
4721
|
+
mark_params(str, value_is_secret, READ_NOW, marks, judged);
|
|
4722
|
+
mark_query_params(str, marks, judged);
|
|
4723
|
+
mark_url_passwords(str, marks);
|
|
4724
|
+
mark_shapes(str, marks);
|
|
4725
|
+
mark_labels(str, marks);
|
|
4726
|
+
}
|
|
4727
|
+
var MASK_MAX_DECODINGS = 2;
|
|
4728
|
+
function encoded_ascii_at(str, p) {
|
|
4729
|
+
if (p + 3 > str.length || str.charCodeAt(p) !== 37) return -1;
|
|
4730
|
+
const hi = hex_digit_value(str.charCodeAt(p + 1));
|
|
4731
|
+
const lo = hi >= 0 ? hex_digit_value(str.charCodeAt(p + 2)) : -1;
|
|
4732
|
+
if (lo < 0) return -1;
|
|
4733
|
+
const c = hi * 16 + lo;
|
|
4734
|
+
return c > 0 && c < 128 ? c : -1;
|
|
4735
|
+
}
|
|
4736
|
+
function mark_decoded_view(str, marks, decodings) {
|
|
4737
|
+
if (decodings >= MASK_MAX_DECODINGS) return;
|
|
4738
|
+
const pieces = [];
|
|
4739
|
+
let last = 0;
|
|
4740
|
+
let p = str.indexOf("%");
|
|
4741
|
+
while (p >= 0) {
|
|
4742
|
+
const c = encoded_ascii_at(str, p);
|
|
4743
|
+
if (c >= 0) {
|
|
4744
|
+
pieces.push(str.substring(last, p), String.fromCharCode(c));
|
|
4745
|
+
last = p + 3;
|
|
4746
|
+
p = str.indexOf("%", last);
|
|
4747
|
+
} else p = str.indexOf("%", p + 1);
|
|
4748
|
+
}
|
|
4749
|
+
if (pieces.length === 0) return;
|
|
4750
|
+
pieces.push(str.substring(last));
|
|
4751
|
+
const view = pieces.join("");
|
|
4752
|
+
const view_marks = new Uint8Array(view.length);
|
|
4753
|
+
mark_inline_rules_of_now(view, view_marks);
|
|
4754
|
+
mark_decoded_view(view, view_marks, decodings + 1);
|
|
4755
|
+
let q = 0;
|
|
4756
|
+
for (let i = 0; i < view.length; i++) {
|
|
4757
|
+
const n = encoded_ascii_at(str, q) >= 0 ? 3 : 1;
|
|
4758
|
+
if (view_marks[i]) mark_range(marks, q, q + n);
|
|
4759
|
+
q += n;
|
|
4760
|
+
}
|
|
4761
|
+
}
|
|
4460
4762
|
function mark_inline_secrets(str, marks) {
|
|
4461
4763
|
const value_is_secret = inline_value_is_secret(str, NAMES_NOW);
|
|
4462
4764
|
const value_is_secret_7_26_9 = inline_value_is_secret(str, NAMES_7_26_9);
|
|
@@ -4464,8 +4766,10 @@ function mark_inline_secrets(str, marks) {
|
|
|
4464
4766
|
if (mark_params(str, value_is_secret, READ_NOW, marks, judged) || value_is_secret !== value_is_secret_7_26_9) mark_params(str, value_is_secret_7_26_9, READ_AS_7_26_9, marks, null);
|
|
4465
4767
|
if (has_shape_js_7_26_20(str)) mark_params(str, value_is_secret, READ_AS_GOBJ_JS_7_26_20, marks, null);
|
|
4466
4768
|
mark_query_params(str, marks, judged);
|
|
4769
|
+
mark_url_passwords(str, marks);
|
|
4467
4770
|
mark_shapes(str, marks);
|
|
4468
4771
|
mark_labels(str, marks);
|
|
4772
|
+
mark_decoded_view(str, marks, 0);
|
|
4469
4773
|
}
|
|
4470
4774
|
/************************************************************
|
|
4471
4775
|
* A text (a command line) with the secrets that can be told
|
|
@@ -4477,13 +4781,14 @@ function mark_inline_secrets(str, marks) {
|
|
|
4477
4781
|
* same for a "name: value", its name in quotes or not (a json, a
|
|
4478
4782
|
* header, a label: "password": x, Authorization: Basic x, bearer:
|
|
4479
4783
|
* tok); and a JWT or the credential after "Bearer " or "Basic ",
|
|
4480
|
-
* wherever they are, whatever names them
|
|
4481
|
-
*
|
|
4482
|
-
*
|
|
4784
|
+
* wherever they are, whatever names them; in a URL or a query
|
|
4785
|
+
* %-encoded inside a value, the same read decoded (mark_decoded_view()).
|
|
4786
|
+
* Each rule judges the text as it came. Return null when there was
|
|
4787
|
+
* nothing to mask. As the C kernel's mask_secrets_inline().
|
|
4483
4788
|
************************************************************/
|
|
4484
4789
|
function mask_secrets_inline(str) {
|
|
4485
4790
|
if (typeof str !== "string") return null;
|
|
4486
|
-
if (str.indexOf("=") < 0 && str.indexOf(":") < 0 && str.indexOf("eyJ") < 0 && !/bearer|basic/i.test(str)) return null;
|
|
4791
|
+
if (str.indexOf("=") < 0 && str.indexOf(":") < 0 && str.indexOf("%") < 0 && str.indexOf("eyJ") < 0 && !/bearer|basic/i.test(str)) return null;
|
|
4487
4792
|
if (str.length > MASK_MAX_BYTES) return MASK_TOO_LARGE;
|
|
4488
4793
|
const marks = new Uint8Array(str.length);
|
|
4489
4794
|
mark_inline_secrets(str, marks);
|
|
@@ -8246,7 +8551,8 @@ var PRIVATE_DATA = {
|
|
|
8246
8551
|
inform_on_close: false,
|
|
8247
8552
|
websocket: null,
|
|
8248
8553
|
inside_on_open: false,
|
|
8249
|
-
retry_ms: 0
|
|
8554
|
+
retry_ms: 0,
|
|
8555
|
+
retry_ms_before_session: 0
|
|
8250
8556
|
};
|
|
8251
8557
|
var __gclass__ = null;
|
|
8252
8558
|
/******************************
|
|
@@ -8297,6 +8603,7 @@ function mt_writing(gobj, path) {
|
|
|
8297
8603
|
function mt_start(gobj) {
|
|
8298
8604
|
let priv = gobj.priv;
|
|
8299
8605
|
priv.retry_ms = 0;
|
|
8606
|
+
priv.retry_ms_before_session = 0;
|
|
8300
8607
|
if (gobj_current_state(gobj) !== "ST_DISCONNECTED") {
|
|
8301
8608
|
gobj_send_event(gobj, "EV_ON_CLOSE", {
|
|
8302
8609
|
url: priv.url,
|
|
@@ -8496,13 +8803,33 @@ function close_websocket(gobj, code = 1e3, reason = "") {
|
|
|
8496
8803
|
}
|
|
8497
8804
|
}
|
|
8498
8805
|
/***************************************************************
|
|
8806
|
+
* Close the channel for a fault of the server: a message for a role
|
|
8807
|
+
* or a yuno that is not this one, an event out of its place.
|
|
8808
|
+
*
|
|
8809
|
+
* Not with 1000: EV_ON_CLOSE would say the session ended well. A
|
|
8810
|
+
* browser closes a WebSocket only with 1000 or 3000-4999 (1002, the
|
|
8811
|
+
* protocol error, throws there), so it is 4002 -- and the server
|
|
8812
|
+
* echoes it, so EV_ON_CLOSE carries it.
|
|
8813
|
+
*
|
|
8814
|
+
* And a session the server broke was not a session reached: the
|
|
8815
|
+
* backoff the ack reset is put back, or a server that breaks every
|
|
8816
|
+
* session is reconnected at the first delay for ever, with an
|
|
8817
|
+
* EV_ON_OPEN and an EV_ON_CLOSE in the app per round.
|
|
8818
|
+
***************************************************************/
|
|
8819
|
+
var CLOSE_PEER_FAULT = 4002;
|
|
8820
|
+
function close_for_peer_fault(gobj, reason) {
|
|
8821
|
+
let priv = gobj.priv;
|
|
8822
|
+
if (gobj_current_state(gobj) === "ST_SESSION") priv.retry_ms = priv.retry_ms_before_session;
|
|
8823
|
+
close_websocket(gobj, CLOSE_PEER_FAULT, reason);
|
|
8824
|
+
}
|
|
8825
|
+
/***************************************************************
|
|
8499
8826
|
* A text of the server -- a frame, the name of an event, of a
|
|
8500
8827
|
* service, of a role -- as a log shows it: masked, then capped on a
|
|
8501
8828
|
* whole character (capped first, a credential the cap cut would
|
|
8502
8829
|
* show its first characters). As the C kernel shows the name of an
|
|
8503
8830
|
* event that is not public (mask_secrets_inline_capped()).
|
|
8504
8831
|
***************************************************************/
|
|
8505
|
-
var PEER_NAME_SHOWN =
|
|
8832
|
+
var PEER_NAME_SHOWN = 128;
|
|
8506
8833
|
var PEER_FRAME_SHOWN = 256;
|
|
8507
8834
|
function peer_text_shown(text, max) {
|
|
8508
8835
|
let s = String(text);
|
|
@@ -8725,7 +9052,8 @@ function ac_on_close(gobj, event, kw, src) {
|
|
|
8725
9052
|
let url = kw.url;
|
|
8726
9053
|
if (kw.ws_seq !== void 0 && kw.ws_seq !== priv.ws_seq) return 0;
|
|
8727
9054
|
set_remote_log_functions();
|
|
8728
|
-
|
|
9055
|
+
const reason_shown = peer_text_shown(kw.reason === void 0 ? "" : kw.reason, PEER_FRAME_SHOWN);
|
|
9056
|
+
if (is_traffic_tracing(gobj)) trace_msg(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${kw.code}, Reason: "${reason_shown}", Clean: ${kw.was_clean})`);
|
|
8729
9057
|
if (priv.websocket) {
|
|
8730
9058
|
priv.websocket.onopen = null;
|
|
8731
9059
|
priv.websocket.onmessage = null;
|
|
@@ -8735,21 +9063,25 @@ function ac_on_close(gobj, event, kw, src) {
|
|
|
8735
9063
|
}
|
|
8736
9064
|
if (priv.inform_on_close) {
|
|
8737
9065
|
priv.inform_on_close = false;
|
|
9066
|
+
if ((!kw.was_clean || kw.code !== 1e3 && kw.code !== 1001) && gobj_is_running(gobj)) log_warning(`${gobj_short_name(gobj)}: session closed ${url} (Code: ${kw.code}, Reason: "${reason_shown}", Clean: ${kw.was_clean})`);
|
|
8738
9067
|
gobj_publish_event(gobj, "EV_ON_CLOSE", {
|
|
8739
9068
|
url,
|
|
8740
9069
|
remote_yuno_name: priv.remote_yuno_name,
|
|
8741
9070
|
remote_yuno_role: priv.remote_yuno_role,
|
|
8742
|
-
remote_yuno_service: priv.remote_yuno_service
|
|
9071
|
+
remote_yuno_service: priv.remote_yuno_service,
|
|
9072
|
+
code: kw.code,
|
|
9073
|
+
reason: reason_shown,
|
|
9074
|
+
was_clean: kw.was_clean
|
|
8743
9075
|
});
|
|
8744
9076
|
} else if (!gobj_is_running(gobj)) {} else {
|
|
8745
|
-
log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${kw.code}, Reason: "${
|
|
9077
|
+
log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${kw.code}, Reason: "${reason_shown}", Clean: ${kw.was_clean})`);
|
|
8746
9078
|
gobj_publish_event(gobj, "EV_ON_OPEN_ERROR", {
|
|
8747
9079
|
url,
|
|
8748
9080
|
remote_yuno_name: priv.remote_yuno_name,
|
|
8749
9081
|
remote_yuno_role: priv.remote_yuno_role,
|
|
8750
9082
|
remote_yuno_service: priv.remote_yuno_service,
|
|
8751
9083
|
code: kw.code,
|
|
8752
|
-
reason:
|
|
9084
|
+
reason: reason_shown,
|
|
8753
9085
|
was_clean: kw.was_clean
|
|
8754
9086
|
});
|
|
8755
9087
|
}
|
|
@@ -8772,7 +9104,8 @@ function ac_on_close(gobj, event, kw, src) {
|
|
|
8772
9104
|
*
|
|
8773
9105
|
* Reset to zero when a session is actually reached
|
|
8774
9106
|
* (ac_identity_card_ack), so a link that flaps once does not carry a
|
|
8775
|
-
* minute-long penalty into its next real drop
|
|
9107
|
+
* minute-long penalty into its next real drop -- and put back when the
|
|
9108
|
+
* server breaks that session (close_for_peer_fault()).
|
|
8776
9109
|
***************************************************************/
|
|
8777
9110
|
function next_retry(gobj) {
|
|
8778
9111
|
let priv = gobj.priv;
|
|
@@ -8822,6 +9155,7 @@ function ac_identity_card_ack(gobj, event, kw, src) {
|
|
|
8822
9155
|
} else {
|
|
8823
9156
|
gobj_change_state(gobj, "ST_SESSION");
|
|
8824
9157
|
priv.inside_on_open = true;
|
|
9158
|
+
priv.retry_ms_before_session = priv.retry_ms;
|
|
8825
9159
|
priv.retry_ms = 0;
|
|
8826
9160
|
if (!priv.inform_on_close) {
|
|
8827
9161
|
priv.inform_on_close = true;
|
|
@@ -8858,19 +9192,26 @@ function ac_on_message(gobj, event, kw, src) {
|
|
|
8858
9192
|
let iev_event = iev_msg.event;
|
|
8859
9193
|
let iev_kw = iev_msg.kw;
|
|
8860
9194
|
if (gobj_current_state(gobj) !== "ST_SESSION") {
|
|
8861
|
-
if (
|
|
8862
|
-
if (!(gobj_send_event(gobj,
|
|
8863
|
-
} else
|
|
8864
|
-
|
|
9195
|
+
if (String(iev_event).toLowerCase() === "ev_identity_card_ack") {
|
|
9196
|
+
if (!(gobj_send_event(gobj, "EV_IDENTITY_CARD_ACK", iev_kw, gobj) < 0)) return 0;
|
|
9197
|
+
} else log_warning(`${gobj_short_name(gobj)}: event UNKNOWN in not-session state ${peer_text_shown(iev_event, PEER_NAME_SHOWN)}`);
|
|
9198
|
+
close_for_peer_fault(gobj, "event out of session");
|
|
8865
9199
|
return -1;
|
|
8866
9200
|
}
|
|
8867
9201
|
iev_msg = null;
|
|
8868
9202
|
let msg_type = msg_iev_get_msg_type(gobj, iev_kw);
|
|
8869
9203
|
let event_id = msg_iev_get_stack(gobj, iev_kw, IEVENT_STACK_ID);
|
|
8870
9204
|
let iev_dst_role = kw_get_str(gobj, event_id, "dst_role", "");
|
|
8871
|
-
if (iev_dst_role.toLowerCase() !== gobj_yuno_role().toLowerCase()) {
|
|
8872
|
-
|
|
8873
|
-
|
|
9205
|
+
if (!empty_string(iev_dst_role) && iev_dst_role.toLowerCase() !== String(gobj_yuno_role()).toLowerCase()) {
|
|
9206
|
+
log_warning(`${gobj_short_name(gobj)}: It's not my role, dst_role: ${peer_text_shown(iev_dst_role, PEER_NAME_SHOWN)}, my_role: ${gobj_yuno_role()}, event: ${peer_text_shown(iev_event, PEER_NAME_SHOWN)}`);
|
|
9207
|
+
close_for_peer_fault(gobj, "not my role");
|
|
9208
|
+
return -1;
|
|
9209
|
+
}
|
|
9210
|
+
let iev_dst_yuno = kw_get_str(gobj, event_id, "dst_yuno", "");
|
|
9211
|
+
if (!empty_string(iev_dst_yuno) && iev_dst_yuno.toLowerCase() !== String(gobj_yuno_name()).toLowerCase()) {
|
|
9212
|
+
log_warning(`${gobj_short_name(gobj)}: It's not my name, dst_yuno: ${peer_text_shown(iev_dst_yuno, PEER_NAME_SHOWN)}, my_name: ${gobj_yuno_name()}, event: ${peer_text_shown(iev_event, PEER_NAME_SHOWN)}`);
|
|
9213
|
+
close_for_peer_fault(gobj, "not my name");
|
|
9214
|
+
return -1;
|
|
8874
9215
|
}
|
|
8875
9216
|
let iev_dst_service = kw_get_str(gobj, event_id, "dst_service", "");
|
|
8876
9217
|
if (msg_type === "__subscribing__") {
|
|
@@ -8881,8 +9222,14 @@ function ac_on_message(gobj, event, kw, src) {
|
|
|
8881
9222
|
log_warning(`${gobj_short_name(gobj)}: unsubscription event ignored, I'm client (service: ${peer_text_shown(iev_dst_service, PEER_NAME_SHOWN)}, event: ${peer_text_shown(iev_event, PEER_NAME_SHOWN)})`);
|
|
8882
9223
|
return -1;
|
|
8883
9224
|
}
|
|
8884
|
-
|
|
8885
|
-
|
|
9225
|
+
const declared = gobj_find_event_type(iev_event, 0, false);
|
|
9226
|
+
if (declared && gobj_has_event(gobj, declared.event_name, 0)) {
|
|
9227
|
+
const own_event = declared.event_name;
|
|
9228
|
+
if (!gobj_has_event(gobj, own_event, event_flag_t.EVF_PUBLIC_EVENT) || own_event === "EV_IDENTITY_CARD_ACK") {
|
|
9229
|
+
log_warning(`${gobj_short_name(gobj)}: event of the transport itself, or out of its place, DROPPED: ev '${peer_text_shown(iev_event, PEER_NAME_SHOWN)}'`);
|
|
9230
|
+
return -1;
|
|
9231
|
+
}
|
|
9232
|
+
gobj_send_event(gobj, own_event, iev_kw, gobj);
|
|
8886
9233
|
return 0;
|
|
8887
9234
|
}
|
|
8888
9235
|
if (!empty_string(iev_dst_service)) {
|
|
@@ -8892,13 +9239,18 @@ function ac_on_message(gobj, event, kw, src) {
|
|
|
8892
9239
|
return 0;
|
|
8893
9240
|
}
|
|
8894
9241
|
if (!gobj_has_event(gobj_service, iev_event, event_flag_t.EVF_PUBLIC_EVENT)) {
|
|
8895
|
-
|
|
9242
|
+
log_warning(`${gobj_short_name(gobj)}: Service found but no event or not public, DROPPED: service '${gobj_short_name(gobj_service)}', ev '${peer_text_shown(iev_event, PEER_NAME_SHOWN)}'`);
|
|
8896
9243
|
return -1;
|
|
8897
9244
|
}
|
|
8898
9245
|
gobj_send_event(gobj_service, iev_event, iev_kw, gobj);
|
|
8899
9246
|
return 0;
|
|
8900
9247
|
}
|
|
8901
|
-
|
|
9248
|
+
let event_type = gobj_find_event_type(iev_event, event_flag_t.EVF_PUBLIC_EVENT, false);
|
|
9249
|
+
if (!event_type) {
|
|
9250
|
+
log_warning(`${gobj_short_name(gobj)}: event that no gclass declares public, DROPPED: ev '${peer_text_shown(iev_event, PEER_NAME_SHOWN)}'`);
|
|
9251
|
+
return -1;
|
|
9252
|
+
}
|
|
9253
|
+
gobj_publish_event(gobj, event_type.event_name, iev_kw);
|
|
8902
9254
|
return 0;
|
|
8903
9255
|
}
|
|
8904
9256
|
/***************************************************************************
|
|
@@ -9018,7 +9370,7 @@ function create_gclass(gclass_name) {
|
|
|
9018
9370
|
__gclass__ = gclass_create(gclass_name, [
|
|
9019
9371
|
["EV_ON_MESSAGE", event_flag_t.EVF_OUTPUT_EVENT],
|
|
9020
9372
|
["EV_IDENTITY_CARD_ACK", event_flag_t.EVF_PUBLIC_EVENT],
|
|
9021
|
-
["EV_ON_ID_NAK", event_flag_t.
|
|
9373
|
+
["EV_ON_ID_NAK", event_flag_t.EVF_OUTPUT_EVENT],
|
|
9022
9374
|
["EV_MT_STATS", event_flag_t.EVF_PUBLIC_EVENT],
|
|
9023
9375
|
["EV_MT_COMMAND", event_flag_t.EVF_PUBLIC_EVENT],
|
|
9024
9376
|
["EV_ON_OPEN", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
|
|
@@ -9113,6 +9465,7 @@ exports.gobj_default_service = gobj_default_service;
|
|
|
9113
9465
|
exports.gobj_deliver_posted_events = gobj_deliver_posted_events;
|
|
9114
9466
|
exports.gobj_destroy = gobj_destroy;
|
|
9115
9467
|
exports.gobj_find_child = gobj_find_child;
|
|
9468
|
+
exports.gobj_find_event_type = gobj_find_event_type;
|
|
9116
9469
|
exports.gobj_find_gobj = gobj_find_gobj;
|
|
9117
9470
|
exports.gobj_find_service = gobj_find_service;
|
|
9118
9471
|
exports.gobj_find_subscribings = gobj_find_subscribings;
|