@yuneta/gobj-js 7.26.21 → 7.26.22
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 +57 -5
- package/dist/gobj-js.cjs.js +860 -199
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +2316 -1846
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +859 -200
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +2165 -1693
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +860 -199
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +2120 -1650
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +860 -199
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +2120 -1650
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/gobj-js.umd.js
CHANGED
|
@@ -219,6 +219,13 @@
|
|
|
219
219
|
var __yuno__ = null;
|
|
220
220
|
var __default_service__ = null;
|
|
221
221
|
var __inside__ = 0;
|
|
222
|
+
var frame_kind_t = Object.freeze({
|
|
223
|
+
FRAME_ACTION: 0,
|
|
224
|
+
FRAME_PUBLICATION: 1,
|
|
225
|
+
FRAME_METHOD: 2,
|
|
226
|
+
FRAME_WATCH: 3
|
|
227
|
+
});
|
|
228
|
+
var __dispatch_top__ = null;
|
|
222
229
|
/**************************************************************************
|
|
223
230
|
* SData - Structured Data
|
|
224
231
|
**************************************************************************/
|
|
@@ -232,7 +239,15 @@
|
|
|
232
239
|
DTP_JSON: 7,
|
|
233
240
|
DTP_POINTER: 8
|
|
234
241
|
});
|
|
242
|
+
var DTP_IS_STRING = (type) => type === data_type_t.DTP_STRING;
|
|
243
|
+
var DTP_IS_BOOLEAN = (type) => type === data_type_t.DTP_BOOLEAN;
|
|
244
|
+
var DTP_IS_INTEGER = (type) => type === data_type_t.DTP_INTEGER;
|
|
245
|
+
var DTP_IS_REAL = (type) => type === data_type_t.DTP_REAL;
|
|
246
|
+
var DTP_IS_LIST = (type) => type === data_type_t.DTP_LIST;
|
|
247
|
+
var DTP_IS_DICT = (type) => type === data_type_t.DTP_DICT;
|
|
248
|
+
var DTP_IS_JSON = (type) => type === data_type_t.DTP_JSON;
|
|
235
249
|
data_type_t.DTP_POINTER;
|
|
250
|
+
var DTP_IS_NUMBER = (type) => DTP_IS_INTEGER(type) || DTP_IS_REAL(type) || DTP_IS_BOOLEAN(type);
|
|
236
251
|
var sdata_flag_t = Object.freeze({
|
|
237
252
|
SDF_NOTACCESS: 1,
|
|
238
253
|
SDF_RD: 2,
|
|
@@ -254,7 +269,8 @@
|
|
|
254
269
|
SDF_AUTHZ_X: 131072,
|
|
255
270
|
SDF_AUTHZ_P: 262144,
|
|
256
271
|
SDF_AUTHZ_S: 524288,
|
|
257
|
-
SDF_AUTHZ_RS: 1048576
|
|
272
|
+
SDF_AUTHZ_RS: 1048576,
|
|
273
|
+
SDF_SECRET: 2097152
|
|
258
274
|
});
|
|
259
275
|
sdata_flag_t.SDF_RD | sdata_flag_t.SDF_WR | sdata_flag_t.SDF_STATS | sdata_flag_t.SDF_PERSIST | sdata_flag_t.SDF_VOLATIL | sdata_flag_t.SDF_RSTATS | sdata_flag_t.SDF_PSTATS;
|
|
260
276
|
sdata_flag_t.SDF_WR | sdata_flag_t.SDF_PERSIST;
|
|
@@ -842,6 +858,260 @@
|
|
|
842
858
|
return 0;
|
|
843
859
|
}
|
|
844
860
|
/***************************************************************************
|
|
861
|
+
* A value of a type, written as text or given as json, read as the C
|
|
862
|
+
* command parser reads a parameter (command_parser.c): the same grammar,
|
|
863
|
+
* the same refusals, so that a C client and a JS client read an attribute
|
|
864
|
+
* value the same way (json2item()). A refusal says why in a short phrase,
|
|
865
|
+
* never the value: it may be a secret.
|
|
866
|
+
***************************************************************************/
|
|
867
|
+
var JSON_INTEGER_TEXT = /^-?(0|[1-9][0-9]*)$/;
|
|
868
|
+
var JSON_NUMBER_TEXT = /^-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?$/;
|
|
869
|
+
var INT64_MIN = -(2n ** 63n);
|
|
870
|
+
var INT64_MAX = 2n ** 63n - 1n;
|
|
871
|
+
var REFUSED_TEXT = "a text that does not read as one";
|
|
872
|
+
function value_has_shape(type, value) {
|
|
873
|
+
if (DTP_IS_STRING(type)) return is_string(value);
|
|
874
|
+
if (DTP_IS_DICT(type)) return is_object(value);
|
|
875
|
+
if (DTP_IS_LIST(type)) return is_array(value);
|
|
876
|
+
if (DTP_IS_NUMBER(type)) return typeof value === "number" || typeof value === "boolean";
|
|
877
|
+
return true;
|
|
878
|
+
}
|
|
879
|
+
function shape_of_value(value) {
|
|
880
|
+
if (is_array(value)) return "an array";
|
|
881
|
+
if (is_object(value)) return "an object";
|
|
882
|
+
if (is_string(value)) return REFUSED_TEXT;
|
|
883
|
+
if (typeof value === "number") return Number.isInteger(value) ? "an integer" : "a real";
|
|
884
|
+
if (typeof value === "boolean") return "a boolean";
|
|
885
|
+
return "null";
|
|
886
|
+
}
|
|
887
|
+
function number_as_type(type, value) {
|
|
888
|
+
if (typeof value === "number" && !Number.isFinite(value)) return {
|
|
889
|
+
value: void 0,
|
|
890
|
+
refused: "a number out of its range"
|
|
891
|
+
};
|
|
892
|
+
if (DTP_IS_BOOLEAN(type)) return {
|
|
893
|
+
value: typeof value === "boolean" ? value : value !== 0,
|
|
894
|
+
refused: null
|
|
895
|
+
};
|
|
896
|
+
if (DTP_IS_REAL(type)) return {
|
|
897
|
+
value: typeof value === "boolean" ? value ? 1 : 0 : value,
|
|
898
|
+
refused: null
|
|
899
|
+
};
|
|
900
|
+
if (typeof value === "boolean") return {
|
|
901
|
+
value: value ? 1 : 0,
|
|
902
|
+
refused: null
|
|
903
|
+
};
|
|
904
|
+
if (!(value >= -0x8000000000000000 && value < 0x8000000000000000)) return {
|
|
905
|
+
value: void 0,
|
|
906
|
+
refused: "a number out of its range"
|
|
907
|
+
};
|
|
908
|
+
if (!Number.isInteger(value)) return {
|
|
909
|
+
value: void 0,
|
|
910
|
+
refused: "a real with decimals"
|
|
911
|
+
};
|
|
912
|
+
return {
|
|
913
|
+
value,
|
|
914
|
+
refused: null
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
function text2parameter(type, s, from_kw) {
|
|
918
|
+
if (!is_string(s)) s = "";
|
|
919
|
+
if (DTP_IS_STRING(type)) return {
|
|
920
|
+
value: s,
|
|
921
|
+
refused: null
|
|
922
|
+
};
|
|
923
|
+
if (DTP_IS_NUMBER(type)) {
|
|
924
|
+
if (s.length === 0) {
|
|
925
|
+
if (from_kw) return {
|
|
926
|
+
value: void 0,
|
|
927
|
+
refused: null
|
|
928
|
+
};
|
|
929
|
+
return {
|
|
930
|
+
value: DTP_IS_BOOLEAN(type) ? false : 0,
|
|
931
|
+
refused: null
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
if (DTP_IS_BOOLEAN(type)) {
|
|
935
|
+
const lower = s.toLowerCase();
|
|
936
|
+
if (lower === "true" || lower === "yes" || lower === "on") return {
|
|
937
|
+
value: true,
|
|
938
|
+
refused: null
|
|
939
|
+
};
|
|
940
|
+
if (lower === "false" || lower === "no" || lower === "off") return {
|
|
941
|
+
value: false,
|
|
942
|
+
refused: null
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
if (!(DTP_IS_REAL(type) ? JSON_NUMBER_TEXT : JSON_INTEGER_TEXT).test(s)) return {
|
|
946
|
+
value: void 0,
|
|
947
|
+
refused: REFUSED_TEXT
|
|
948
|
+
};
|
|
949
|
+
if (DTP_IS_REAL(type)) {
|
|
950
|
+
const d = Number(s);
|
|
951
|
+
if (!Number.isFinite(d)) return {
|
|
952
|
+
value: void 0,
|
|
953
|
+
refused: "a number out of its range"
|
|
954
|
+
};
|
|
955
|
+
return {
|
|
956
|
+
value: d,
|
|
957
|
+
refused: null
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
const n = BigInt(s);
|
|
961
|
+
if (n < INT64_MIN || n > INT64_MAX) return {
|
|
962
|
+
value: void 0,
|
|
963
|
+
refused: "a number out of its range"
|
|
964
|
+
};
|
|
965
|
+
if (DTP_IS_BOOLEAN(type)) return {
|
|
966
|
+
value: n !== 0n,
|
|
967
|
+
refused: null
|
|
968
|
+
};
|
|
969
|
+
return {
|
|
970
|
+
value: Number(n),
|
|
971
|
+
refused: null
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
if (DTP_IS_DICT(type) || DTP_IS_LIST(type)) {
|
|
975
|
+
let jn;
|
|
976
|
+
try {
|
|
977
|
+
jn = JSON.parse(s);
|
|
978
|
+
} catch (e) {
|
|
979
|
+
return {
|
|
980
|
+
value: void 0,
|
|
981
|
+
refused: REFUSED_TEXT
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
if (!value_has_shape(type, jn)) return {
|
|
985
|
+
value: void 0,
|
|
986
|
+
refused: REFUSED_TEXT
|
|
987
|
+
};
|
|
988
|
+
return {
|
|
989
|
+
value: jn,
|
|
990
|
+
refused: null
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
if (DTP_IS_JSON(type)) try {
|
|
994
|
+
return {
|
|
995
|
+
value: JSON.parse(s),
|
|
996
|
+
refused: null
|
|
997
|
+
};
|
|
998
|
+
} catch (e) {
|
|
999
|
+
const t = s.replace(/^[ \t]+/, "");
|
|
1000
|
+
if (t.startsWith("{") || t.startsWith("[") || t.startsWith("\"")) return {
|
|
1001
|
+
value: void 0,
|
|
1002
|
+
refused: REFUSED_TEXT
|
|
1003
|
+
};
|
|
1004
|
+
return {
|
|
1005
|
+
value: s,
|
|
1006
|
+
refused: null
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
return {
|
|
1010
|
+
value: void 0,
|
|
1011
|
+
refused: REFUSED_TEXT
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
/***************************************************************************
|
|
1015
|
+
* A value of `type` written as TEXT, read as the C parser reads a
|
|
1016
|
+
* parameter on the command line (command_parameter_from_text()): an empty
|
|
1017
|
+
* text is 0 or false. Return {value, refused}: `value` undefined when the
|
|
1018
|
+
* text does not read as one, `refused` saying why.
|
|
1019
|
+
***************************************************************************/
|
|
1020
|
+
function command_parameter_from_text(type, text) {
|
|
1021
|
+
const r = text2parameter(type, text, false);
|
|
1022
|
+
if (r.value === void 0 && !r.refused) r.refused = REFUSED_TEXT;
|
|
1023
|
+
return r;
|
|
1024
|
+
}
|
|
1025
|
+
/***************************************************************************
|
|
1026
|
+
* A value of `type` given as JSON, read as the C parser reads a
|
|
1027
|
+
* parameter given in kw (command_parameter_from_json()): a string as
|
|
1028
|
+
* command_parameter_from_text() reads a text (a string with a NUL inside
|
|
1029
|
+
* refused), a number or a boolean as the EXACT type (an integer to a
|
|
1030
|
+
* DTP_REAL is its real, a boolean to a DTP_INTEGER 1 or 0, 2.7 to a
|
|
1031
|
+
* DTP_INTEGER refused), an object or a list of its shape as it is, any
|
|
1032
|
+
* other shape refused. Return {value, refused}: `value` undefined and
|
|
1033
|
+
* `refused` saying why, or `refused` null when there is NO value (a null,
|
|
1034
|
+
* undefined, or an empty text given to a number).
|
|
1035
|
+
***************************************************************************/
|
|
1036
|
+
function command_parameter_from_json(type, value) {
|
|
1037
|
+
if (value === void 0 || value === null) {
|
|
1038
|
+
if (DTP_IS_JSON(type) && value === null) return {
|
|
1039
|
+
value: null,
|
|
1040
|
+
refused: null
|
|
1041
|
+
};
|
|
1042
|
+
return {
|
|
1043
|
+
value: void 0,
|
|
1044
|
+
refused: null
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
const nul_inside = is_string(value) && value.indexOf("\0") >= 0;
|
|
1048
|
+
if (DTP_IS_JSON(type)) {
|
|
1049
|
+
if (!is_string(value) || nul_inside) return {
|
|
1050
|
+
value,
|
|
1051
|
+
refused: null
|
|
1052
|
+
};
|
|
1053
|
+
const r = text2parameter(type, value, true);
|
|
1054
|
+
return r.value === void 0 ? {
|
|
1055
|
+
value,
|
|
1056
|
+
refused: null
|
|
1057
|
+
} : r;
|
|
1058
|
+
}
|
|
1059
|
+
if (!(DTP_IS_STRING(type) || DTP_IS_DICT(type) || DTP_IS_LIST(type) || DTP_IS_NUMBER(type))) return {
|
|
1060
|
+
value,
|
|
1061
|
+
refused: null
|
|
1062
|
+
};
|
|
1063
|
+
if (nul_inside) return {
|
|
1064
|
+
value: void 0,
|
|
1065
|
+
refused: "a text with a NUL in it"
|
|
1066
|
+
};
|
|
1067
|
+
if (is_string(value) && !DTP_IS_STRING(type)) return text2parameter(type, value, true);
|
|
1068
|
+
if (!value_has_shape(type, value)) return {
|
|
1069
|
+
value: void 0,
|
|
1070
|
+
refused: shape_of_value(value)
|
|
1071
|
+
};
|
|
1072
|
+
if (DTP_IS_NUMBER(type)) return number_as_type(type, value);
|
|
1073
|
+
return {
|
|
1074
|
+
value,
|
|
1075
|
+
refused: null
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
/***************************************************************************
|
|
1079
|
+
* A value json2item() refuses: the attr, its type and why, and the value
|
|
1080
|
+
* as a log may show it (a SDF_SECRET one never; any other masked, then
|
|
1081
|
+
* capped on a whole character, as in C)
|
|
1082
|
+
***************************************************************************/
|
|
1083
|
+
var ATTR_VALUE_SHOWN = 64;
|
|
1084
|
+
var TYPES_READ = [
|
|
1085
|
+
data_type_t.DTP_BOOLEAN,
|
|
1086
|
+
data_type_t.DTP_INTEGER,
|
|
1087
|
+
data_type_t.DTP_REAL,
|
|
1088
|
+
data_type_t.DTP_LIST,
|
|
1089
|
+
data_type_t.DTP_DICT
|
|
1090
|
+
];
|
|
1091
|
+
function log_attr_value_refused(gobj, it, value, refused) {
|
|
1092
|
+
const types = {
|
|
1093
|
+
[data_type_t.DTP_BOOLEAN]: "a boolean",
|
|
1094
|
+
[data_type_t.DTP_INTEGER]: "an integer",
|
|
1095
|
+
[data_type_t.DTP_REAL]: "a real",
|
|
1096
|
+
[data_type_t.DTP_LIST]: "a json array",
|
|
1097
|
+
[data_type_t.DTP_DICT]: "a json object"
|
|
1098
|
+
};
|
|
1099
|
+
let shown;
|
|
1100
|
+
if (it.flag & sdata_flag_t.SDF_SECRET) shown = "********";
|
|
1101
|
+
else {
|
|
1102
|
+
shown = is_string(value) ? value : String(JSON.stringify(value === void 0 ? null : value));
|
|
1103
|
+
const masked = mask_secrets_inline(shown);
|
|
1104
|
+
if (masked !== null) shown = masked;
|
|
1105
|
+
if (shown.length > ATTR_VALUE_SHOWN) {
|
|
1106
|
+
let n = ATTR_VALUE_SHOWN;
|
|
1107
|
+
const code = shown.charCodeAt(n);
|
|
1108
|
+
if (code >= 56320 && code <= 57343) n--;
|
|
1109
|
+
shown = shown.substring(0, n);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
log_error(`${gobj_short_name(gobj)}: Attribute value of the wrong type, not written: attr '${it.name}', type ${types[it.type] || "a value of its type"}, got ${refused || "no value (a null, or an empty text)"}, value '${shown}'`);
|
|
1113
|
+
}
|
|
1114
|
+
/***************************************************************************
|
|
845
1115
|
* Set array values to sdata, from json or binary
|
|
846
1116
|
***************************************************************************/
|
|
847
1117
|
function json2item(gobj, sdata, it, jn_value_) {
|
|
@@ -856,44 +1126,18 @@
|
|
|
856
1126
|
}
|
|
857
1127
|
break;
|
|
858
1128
|
case data_type_t.DTP_BOOLEAN:
|
|
859
|
-
jn_value2 = parseBoolean(jn_value_);
|
|
860
|
-
break;
|
|
861
1129
|
case data_type_t.DTP_INTEGER:
|
|
862
|
-
jn_value2 = parseInt(jn_value_);
|
|
863
|
-
if (isNaN(jn_value2)) {
|
|
864
|
-
log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
|
|
865
|
-
return -1;
|
|
866
|
-
}
|
|
867
|
-
break;
|
|
868
1130
|
case data_type_t.DTP_REAL:
|
|
869
|
-
jn_value2 = Number(jn_value_);
|
|
870
|
-
if (isNaN(jn_value2)) {
|
|
871
|
-
log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
|
|
872
|
-
return -1;
|
|
873
|
-
}
|
|
874
|
-
break;
|
|
875
1131
|
case data_type_t.DTP_LIST:
|
|
876
|
-
if (is_string(jn_value_)) try {
|
|
877
|
-
jn_value2 = JSON.parse(jn_value_);
|
|
878
|
-
} catch (error) {
|
|
879
|
-
log_error(`JSON parse error: ${error.message}`);
|
|
880
|
-
}
|
|
881
|
-
else jn_value2 = jn_value_;
|
|
882
|
-
if (!is_array(jn_value2)) {
|
|
883
|
-
log_error(`attr must be an array: ${it.name}`);
|
|
884
|
-
return -1;
|
|
885
|
-
}
|
|
886
|
-
break;
|
|
887
1132
|
case data_type_t.DTP_DICT:
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
return -1;
|
|
1133
|
+
{
|
|
1134
|
+
if (jn_value_ === void 0) return 0;
|
|
1135
|
+
const r = command_parameter_from_json(it.type, jn_value_);
|
|
1136
|
+
if (r.value === void 0) {
|
|
1137
|
+
log_attr_value_refused(gobj, it, jn_value_, r.refused);
|
|
1138
|
+
return -1;
|
|
1139
|
+
}
|
|
1140
|
+
jn_value2 = r.value;
|
|
897
1141
|
}
|
|
898
1142
|
break;
|
|
899
1143
|
case data_type_t.DTP_JSON:
|
|
@@ -1468,6 +1712,8 @@
|
|
|
1468
1712
|
return;
|
|
1469
1713
|
}
|
|
1470
1714
|
if (gobj.__refs__ > 0) log_error(`${gobj_short_name(gobj)}: gobj DESTROYING with references: ${gobj.__refs__}`);
|
|
1715
|
+
if (!(gobj.parent && gobj_is_destroying(gobj.parent))) check_destroy_under_running_code(gobj);
|
|
1716
|
+
mark_dispatch_frames_destroyed(gobj);
|
|
1471
1717
|
if (gobj.playing) {
|
|
1472
1718
|
log_error(`Destroying a PLAYING gobj: ${gobj_full_name(gobj)}`);
|
|
1473
1719
|
gobj_pause(gobj);
|
|
@@ -1532,10 +1778,44 @@
|
|
|
1532
1778
|
if (__trace_gobj_start_stop__(gobj)) trace_machine(sprintf("⏺ ⏺ start: %s", gobj_full_name(gobj)));
|
|
1533
1779
|
gobj.running = true;
|
|
1534
1780
|
let ret = 0;
|
|
1535
|
-
if (gobj.gclass.gmt.mt_start)
|
|
1781
|
+
if (gobj.gclass.gmt.mt_start) {
|
|
1782
|
+
const frame = push_dispatch_frame(gobj, "mt_start", frame_kind_t.FRAME_METHOD);
|
|
1783
|
+
try {
|
|
1784
|
+
ret = gobj.gclass.gmt.mt_start(gobj);
|
|
1785
|
+
} finally {
|
|
1786
|
+
pop_dispatch_frame(frame);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1536
1789
|
return ret;
|
|
1537
1790
|
}
|
|
1538
1791
|
/***************************************************************************
|
|
1792
|
+
* Start a gobj in a walk of its tree, and say whether that destroyed it.
|
|
1793
|
+
*
|
|
1794
|
+
* A gclass may end itself in its own mt_start or mt_stop, and a walk of
|
|
1795
|
+
* the tree must not go down into the children of a gobj that is gone.
|
|
1796
|
+
***************************************************************************/
|
|
1797
|
+
function start_destroys_it(gobj) {
|
|
1798
|
+
const frame = push_dispatch_frame(gobj, "gobj_start", frame_kind_t.FRAME_WATCH);
|
|
1799
|
+
try {
|
|
1800
|
+
gobj_start(gobj);
|
|
1801
|
+
} finally {
|
|
1802
|
+
pop_dispatch_frame(frame);
|
|
1803
|
+
}
|
|
1804
|
+
return frame.destroyed;
|
|
1805
|
+
}
|
|
1806
|
+
/***************************************************************************
|
|
1807
|
+
* Stop a gobj in a walk of its tree, and say whether that destroyed it.
|
|
1808
|
+
***************************************************************************/
|
|
1809
|
+
function stop_destroys_it(gobj) {
|
|
1810
|
+
const frame = push_dispatch_frame(gobj, "gobj_stop", frame_kind_t.FRAME_WATCH);
|
|
1811
|
+
try {
|
|
1812
|
+
gobj_stop(gobj);
|
|
1813
|
+
} finally {
|
|
1814
|
+
pop_dispatch_frame(frame);
|
|
1815
|
+
}
|
|
1816
|
+
return frame.destroyed;
|
|
1817
|
+
}
|
|
1818
|
+
/***************************************************************************
|
|
1539
1819
|
* Start all children of the gobj.
|
|
1540
1820
|
***************************************************************************/
|
|
1541
1821
|
function cb_start_child(child, user_data, user_data2) {
|
|
@@ -1556,7 +1836,9 @@
|
|
|
1556
1836
|
function cb_start_child_tree(child, user_data, user_data2) {
|
|
1557
1837
|
if (child.gclass.gclass_flag & gclass_flag_t.gcflag_manual_start) return 1;
|
|
1558
1838
|
if (gobj_is_disabled(child)) return 1;
|
|
1559
|
-
if (!gobj_is_running(child))
|
|
1839
|
+
if (!gobj_is_running(child)) {
|
|
1840
|
+
if (start_destroys_it(child)) return 1;
|
|
1841
|
+
}
|
|
1560
1842
|
return 0;
|
|
1561
1843
|
}
|
|
1562
1844
|
function gobj_start_tree(gobj) {
|
|
@@ -1567,7 +1849,9 @@
|
|
|
1567
1849
|
if (__trace_gobj_start_stop__(gobj)) trace_machine(sprintf("⏺ ⏺ ⏺ ⏺ start_tree: %s", gobj_full_name(gobj)));
|
|
1568
1850
|
if (gobj.gclass.gclass_flag & gclass_flag_t.gcflag_manual_start) return 0;
|
|
1569
1851
|
else if (gobj.disabled) return 0;
|
|
1570
|
-
else if (!gobj.running)
|
|
1852
|
+
else if (!gobj.running) {
|
|
1853
|
+
if (start_destroys_it(gobj)) return 0;
|
|
1854
|
+
}
|
|
1571
1855
|
return gobj_walk_gobj_children_tree(gobj, walk_type_t.WALK_TOP2BOTTOM, cb_start_child_tree, 0, 0);
|
|
1572
1856
|
}
|
|
1573
1857
|
/************************************************************
|
|
@@ -1589,14 +1873,23 @@
|
|
|
1589
1873
|
if (__trace_gobj_start_stop__(gobj)) trace_machine(sprintf("⏹ ⏹ stop: %s", gobj_full_name(gobj)));
|
|
1590
1874
|
gobj.running = false;
|
|
1591
1875
|
let ret = 0;
|
|
1592
|
-
if (gobj.gclass.gmt.mt_stop)
|
|
1876
|
+
if (gobj.gclass.gmt.mt_stop) {
|
|
1877
|
+
const frame = push_dispatch_frame(gobj, "mt_stop", frame_kind_t.FRAME_METHOD);
|
|
1878
|
+
try {
|
|
1879
|
+
ret = gobj.gclass.gmt.mt_stop(gobj);
|
|
1880
|
+
} finally {
|
|
1881
|
+
pop_dispatch_frame(frame);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1593
1884
|
return ret;
|
|
1594
1885
|
}
|
|
1595
1886
|
/***************************************************************************
|
|
1596
1887
|
* Stop all children of the gobj.
|
|
1597
1888
|
***************************************************************************/
|
|
1598
1889
|
function cb_stop_child(child, user_data, user_data2) {
|
|
1599
|
-
if (gobj_is_running(child))
|
|
1890
|
+
if (gobj_is_running(child)) {
|
|
1891
|
+
if (stop_destroys_it(child)) return 1;
|
|
1892
|
+
}
|
|
1600
1893
|
return 0;
|
|
1601
1894
|
}
|
|
1602
1895
|
function gobj_stop_children(gobj) {
|
|
@@ -1615,7 +1908,9 @@
|
|
|
1615
1908
|
return -1;
|
|
1616
1909
|
}
|
|
1617
1910
|
if (__trace_gobj_start_stop__(gobj)) trace_machine(sprintf("⏹ ⏹ ⏹ ⏹ stop_tree: %s", gobj_full_name(gobj)));
|
|
1618
|
-
if (gobj_is_running(gobj))
|
|
1911
|
+
if (gobj_is_running(gobj)) {
|
|
1912
|
+
if (stop_destroys_it(gobj)) return 0;
|
|
1913
|
+
}
|
|
1619
1914
|
return gobj_walk_gobj_children_tree(gobj, walk_type_t.WALK_TOP2BOTTOM, cb_stop_child, 0, 0);
|
|
1620
1915
|
}
|
|
1621
1916
|
/************************************************************
|
|
@@ -1647,8 +1942,13 @@
|
|
|
1647
1942
|
gobj.playing = true;
|
|
1648
1943
|
let ret = 0;
|
|
1649
1944
|
if (gobj.gclass.gmt.mt_play) {
|
|
1650
|
-
|
|
1651
|
-
|
|
1945
|
+
const frame = push_dispatch_frame(gobj, "mt_play", frame_kind_t.FRAME_METHOD);
|
|
1946
|
+
try {
|
|
1947
|
+
ret = gobj.gclass.gmt.mt_play(gobj);
|
|
1948
|
+
} finally {
|
|
1949
|
+
pop_dispatch_frame(frame);
|
|
1950
|
+
}
|
|
1951
|
+
if ((ret < 0 || ret === false) && !frame.destroyed) gobj.playing = false;
|
|
1652
1952
|
}
|
|
1653
1953
|
return ret;
|
|
1654
1954
|
}
|
|
@@ -1666,8 +1966,14 @@
|
|
|
1666
1966
|
}
|
|
1667
1967
|
if (__trace_gobj_start_stop__(gobj)) trace_machine(sprintf("⏸ ⏸ pause: %s", gobj_full_name(gobj)));
|
|
1668
1968
|
gobj.playing = false;
|
|
1669
|
-
if (gobj.gclass.gmt.mt_pause)
|
|
1670
|
-
|
|
1969
|
+
if (gobj.gclass.gmt.mt_pause) {
|
|
1970
|
+
const frame = push_dispatch_frame(gobj, "mt_pause", frame_kind_t.FRAME_METHOD);
|
|
1971
|
+
try {
|
|
1972
|
+
return gobj.gclass.gmt.mt_pause(gobj);
|
|
1973
|
+
} finally {
|
|
1974
|
+
pop_dispatch_frame(frame);
|
|
1975
|
+
}
|
|
1976
|
+
} else return 0;
|
|
1671
1977
|
}
|
|
1672
1978
|
/************************************************************
|
|
1673
1979
|
*
|
|
@@ -2220,14 +2526,7 @@
|
|
|
2220
2526
|
if (ss.length <= 1) {
|
|
2221
2527
|
let key = path;
|
|
2222
2528
|
if (key in jn_attrs) {
|
|
2223
|
-
if (Object.prototype.hasOwnProperty.call(jn_attrs, key))
|
|
2224
|
-
jn_attrs[key] = value;
|
|
2225
|
-
if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, key)) gobj.priv[key] = value;
|
|
2226
|
-
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2227
|
-
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, key);
|
|
2228
|
-
}
|
|
2229
|
-
return 0;
|
|
2230
|
-
}
|
|
2529
|
+
if (Object.prototype.hasOwnProperty.call(jn_attrs, key)) return write_attr_value(gobj, key, value);
|
|
2231
2530
|
}
|
|
2232
2531
|
log_error(sprintf("gobj_write_attr(%s): attr not found '%s'", gobj_short_name(gobj), key));
|
|
2233
2532
|
return -1;
|
|
@@ -2243,14 +2542,7 @@
|
|
|
2243
2542
|
}
|
|
2244
2543
|
let jn_attrs = gobj.jn_attrs;
|
|
2245
2544
|
if (key in jn_attrs) {
|
|
2246
|
-
if (Object.prototype.hasOwnProperty.call(jn_attrs, key))
|
|
2247
|
-
jn_attrs[key] = value;
|
|
2248
|
-
if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, key)) gobj.priv[key] = value;
|
|
2249
|
-
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2250
|
-
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, key);
|
|
2251
|
-
}
|
|
2252
|
-
return 0;
|
|
2253
|
-
}
|
|
2545
|
+
if (Object.prototype.hasOwnProperty.call(jn_attrs, key)) return write_attr_value(gobj, key, value);
|
|
2254
2546
|
}
|
|
2255
2547
|
break;
|
|
2256
2548
|
}
|
|
@@ -2258,6 +2550,49 @@
|
|
|
2258
2550
|
return -1;
|
|
2259
2551
|
}
|
|
2260
2552
|
/***************************************************************************
|
|
2553
|
+
* The value written to the attr `key` of `gobj`, read as its type as the C
|
|
2554
|
+
* kernel reads it (json2item(): it writes priv and calls mt_writing too).
|
|
2555
|
+
* Up to 7.26.21 gobj_write_attr() wrote it raw.
|
|
2556
|
+
***************************************************************************/
|
|
2557
|
+
function write_attr_value(gobj, key, value) {
|
|
2558
|
+
const it = gobj_attr_desc(gobj, key, false);
|
|
2559
|
+
if (!it) {
|
|
2560
|
+
log_error(sprintf("gobj_write_attr(%s): attr without description '%s'", gobj_short_name(gobj), key));
|
|
2561
|
+
return -1;
|
|
2562
|
+
}
|
|
2563
|
+
if (value === void 0 && TYPES_READ.includes(it.type)) {
|
|
2564
|
+
log_attr_value_refused(gobj, it, value, null);
|
|
2565
|
+
return -1;
|
|
2566
|
+
}
|
|
2567
|
+
return json2item(gobj, gobj.jn_attrs, it, value);
|
|
2568
|
+
}
|
|
2569
|
+
/***************************************************************************
|
|
2570
|
+
* The value a typed writer writes, read as ITS type by the grammar of
|
|
2571
|
+
* json2item() (a C writer takes its C type: a string is never read as a
|
|
2572
|
+
* number there). Return {value} or {refused} (logged): the attr keeps its
|
|
2573
|
+
* value. A string writer never refuses: null and undefined are "", any
|
|
2574
|
+
* other json its text, as a DTP_STRING attr reads them.
|
|
2575
|
+
***************************************************************************/
|
|
2576
|
+
function typed_writer_value(gobj, name, type, value) {
|
|
2577
|
+
if (DTP_IS_STRING(type)) {
|
|
2578
|
+
if (value === null || value === void 0) return { value: "" };
|
|
2579
|
+
return { value: is_string(value) ? value : String(JSON.stringify(value)) };
|
|
2580
|
+
}
|
|
2581
|
+
const r = command_parameter_from_json(type, value);
|
|
2582
|
+
if (r.value === void 0) {
|
|
2583
|
+
let holder = gobj;
|
|
2584
|
+
while (holder && !gobj_has_attr(holder, name)) holder = holder.bottom_gobj;
|
|
2585
|
+
const it = holder ? gobj_attr_desc(holder, name, false) : null;
|
|
2586
|
+
log_attr_value_refused(gobj, {
|
|
2587
|
+
name,
|
|
2588
|
+
type,
|
|
2589
|
+
flag: it ? it.flag : 0
|
|
2590
|
+
}, value, r.refused);
|
|
2591
|
+
return { refused: true };
|
|
2592
|
+
}
|
|
2593
|
+
return { value: r.value };
|
|
2594
|
+
}
|
|
2595
|
+
/***************************************************************************
|
|
2261
2596
|
* WRITE - high level
|
|
2262
2597
|
***************************************************************************/
|
|
2263
2598
|
function sdata_write_default_values(gobj, include_flag, exclude_flag) {
|
|
@@ -2305,7 +2640,9 @@
|
|
|
2305
2640
|
function gobj_write_bool_attr(gobj, name, value) {
|
|
2306
2641
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2307
2642
|
if (hs) {
|
|
2308
|
-
|
|
2643
|
+
const v = typed_writer_value(gobj, name, data_type_t.DTP_BOOLEAN, value);
|
|
2644
|
+
if (v.refused) return -1;
|
|
2645
|
+
hs[name] = v.value;
|
|
2309
2646
|
if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, name)) gobj.priv[name] = hs[name];
|
|
2310
2647
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2311
2648
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
@@ -2321,7 +2658,9 @@
|
|
|
2321
2658
|
function gobj_write_integer_attr(gobj, name, value) {
|
|
2322
2659
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2323
2660
|
if (hs) {
|
|
2324
|
-
|
|
2661
|
+
const v = typed_writer_value(gobj, name, data_type_t.DTP_INTEGER, value);
|
|
2662
|
+
if (v.refused) return -1;
|
|
2663
|
+
hs[name] = v.value;
|
|
2325
2664
|
if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, name)) gobj.priv[name] = hs[name];
|
|
2326
2665
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2327
2666
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
@@ -2337,7 +2676,9 @@
|
|
|
2337
2676
|
function gobj_write_str_attr(gobj, name, value) {
|
|
2338
2677
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2339
2678
|
if (hs) {
|
|
2340
|
-
|
|
2679
|
+
const v = typed_writer_value(gobj, name, data_type_t.DTP_STRING, value);
|
|
2680
|
+
if (v.refused) return -1;
|
|
2681
|
+
hs[name] = v.value;
|
|
2341
2682
|
if (is_object(gobj.priv) && Object.prototype.hasOwnProperty.call(gobj.priv, name)) gobj.priv[name] = hs[name];
|
|
2342
2683
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2343
2684
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
@@ -2547,6 +2888,84 @@
|
|
|
2547
2888
|
__dl_posted_events__ = __dl_posted_events__.filter((msg) => msg.dst !== gobj);
|
|
2548
2889
|
}
|
|
2549
2890
|
/************************************************************
|
|
2891
|
+
* A dispatch begins: its frame goes on top of the chain.
|
|
2892
|
+
* Every push is paired with a pop in a `finally`: an action
|
|
2893
|
+
* that throws must not leave its frame on the chain.
|
|
2894
|
+
************************************************************/
|
|
2895
|
+
function push_dispatch_frame(gobj, event, kind) {
|
|
2896
|
+
const frame = {
|
|
2897
|
+
prev: __dispatch_top__,
|
|
2898
|
+
gobj,
|
|
2899
|
+
event,
|
|
2900
|
+
kind,
|
|
2901
|
+
destroyed: false
|
|
2902
|
+
};
|
|
2903
|
+
__dispatch_top__ = frame;
|
|
2904
|
+
return frame;
|
|
2905
|
+
}
|
|
2906
|
+
function pop_dispatch_frame(frame) {
|
|
2907
|
+
__dispatch_top__ = frame.prev;
|
|
2908
|
+
}
|
|
2909
|
+
/************************************************************
|
|
2910
|
+
* Every dispatch in progress of `gobj` learns that it is
|
|
2911
|
+
* destroyed. Only its own frames: each child destroyed with
|
|
2912
|
+
* it marks its own, in its own gobj_destroy().
|
|
2913
|
+
************************************************************/
|
|
2914
|
+
function mark_dispatch_frames_destroyed(gobj) {
|
|
2915
|
+
for (let f = __dispatch_top__; f; f = f.prev) if (f.gobj === gobj) f.destroyed = true;
|
|
2916
|
+
}
|
|
2917
|
+
/************************************************************
|
|
2918
|
+
* Is the innermost live publication of `gobj` its EV_STOPPED?
|
|
2919
|
+
* Then the stop contract holds for it: that is the last thing
|
|
2920
|
+
* it does with itself.
|
|
2921
|
+
************************************************************/
|
|
2922
|
+
function said_farewell(gobj) {
|
|
2923
|
+
for (let f = __dispatch_top__; f; f = f.prev) if (f.kind === frame_kind_t.FRAME_PUBLICATION && !f.destroyed && f.gobj === gobj) return f.event === "EV_STOPPED";
|
|
2924
|
+
return false;
|
|
2925
|
+
}
|
|
2926
|
+
/************************************************************
|
|
2927
|
+
* A gobj must not be destroyed under code that is still
|
|
2928
|
+
* running on it -- the C kernel's check, with its exemptions
|
|
2929
|
+
* and its fields, so both runtimes report the same defect the
|
|
2930
|
+
* same way.
|
|
2931
|
+
*
|
|
2932
|
+
* `gobj` is about to be destroyed, and with it its whole
|
|
2933
|
+
* subtree. Every live frame of a gobj of that subtree is code
|
|
2934
|
+
* that goes on when the destroy returns, on a gobj that is gone
|
|
2935
|
+
* (C_TIMER right after its EV_TIMEOUT). It is an ERROR, except
|
|
2936
|
+
* for:
|
|
2937
|
+
*
|
|
2938
|
+
* - the innermost frame: it is the code that destroys, and
|
|
2939
|
+
* knows it (a gobj that destroys itself in its own action);
|
|
2940
|
+
*
|
|
2941
|
+
* - the frames of a gobj whose innermost publication is
|
|
2942
|
+
* EV_STOPPED: the stop contract, its host destroys it there;
|
|
2943
|
+
*
|
|
2944
|
+
* - the watch frames, which run no gclass code of their own.
|
|
2945
|
+
*
|
|
2946
|
+
* The destroy goes on: this only says it, once. The fix is to
|
|
2947
|
+
* defer the destroy with gobj_post_event().
|
|
2948
|
+
************************************************************/
|
|
2949
|
+
function check_destroy_under_running_code(gobj) {
|
|
2950
|
+
const top = __dispatch_top__;
|
|
2951
|
+
if (!top) return;
|
|
2952
|
+
for (let f = top.prev; f; f = f.prev) {
|
|
2953
|
+
if (f.destroyed || f.kind === frame_kind_t.FRAME_WATCH) continue;
|
|
2954
|
+
let in_tree = false;
|
|
2955
|
+
for (let p = f.gobj; p; p = p.parent) if (p === gobj) {
|
|
2956
|
+
in_tree = true;
|
|
2957
|
+
break;
|
|
2958
|
+
}
|
|
2959
|
+
if (!in_tree) continue;
|
|
2960
|
+
if (said_farewell(f.gobj)) continue;
|
|
2961
|
+
const destroyer = top.destroyed ? "(destroyed)" : gobj_full_name(top.gobj);
|
|
2962
|
+
const stack = String((/* @__PURE__ */ new Error()).stack || "").split("\n").slice(2).join("\n");
|
|
2963
|
+
if (f.kind === frame_kind_t.FRAME_PUBLICATION) log_error(`Destroying a gobj while its tree is publishing: destroying ${gobj_full_name(gobj)}, publisher ${gobj_full_name(f.gobj)}, event ${f.event || ""}, destroyer ${destroyer}, inner_event ${top.event || ""}. Defer it with gobj_post_event(): a subscriber must not destroy the tree of its publisher synchronously. stack:\n${stack}`);
|
|
2964
|
+
else log_error(`Destroying a gobj while one of its actions is still running: destroying ${gobj_full_name(gobj)}, running ${gobj_full_name(f.gobj)}, event ${f.event || ""}, destroyer ${destroyer}, inner_event ${top.event || ""}. Defer it with gobj_post_event(): an inner dispatch must not destroy a gobj that an outer one is running on. stack:\n${stack}`);
|
|
2965
|
+
return;
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
/************************************************************
|
|
2550
2969
|
* send_event
|
|
2551
2970
|
************************************************************/
|
|
2552
2971
|
function gobj_send_event(dst, event, kw, src) {
|
|
@@ -2578,7 +2997,12 @@
|
|
|
2578
2997
|
}
|
|
2579
2998
|
}
|
|
2580
2999
|
}
|
|
2581
|
-
|
|
3000
|
+
const frame = push_dispatch_frame(dst, event, frame_kind_t.FRAME_ACTION);
|
|
3001
|
+
try {
|
|
3002
|
+
return dst.gclass.gmt.mt_inject_event(dst, event, kw, src);
|
|
3003
|
+
} finally {
|
|
3004
|
+
pop_dispatch_frame(frame);
|
|
3005
|
+
}
|
|
2582
3006
|
}
|
|
2583
3007
|
if (tracea) trace_machine(sprintf("📛 mach(%s%s^%s), st: %s, ev: %s, 📛📛ERROR Event NOT DEFINED in state📛📛, from(%s%s^%s)", !dst.running ? "!!" : "", gobj_gclass_name(dst), gobj_name(dst), state.state_name, event ? event : "", src && !src.running ? "!!" : "", gobj_gclass_name(src), gobj_name(src)));
|
|
2584
3008
|
log_error(`📛📛 Event NOT DEFINED in state 📛📛: ${gobj_short_name(dst)}, ${state.state_name}, ${event}`);
|
|
@@ -2598,6 +3022,7 @@
|
|
|
2598
3022
|
}
|
|
2599
3023
|
}
|
|
2600
3024
|
}
|
|
3025
|
+
const frame = push_dispatch_frame(dst, event, frame_kind_t.FRAME_ACTION);
|
|
2601
3026
|
if (event_action.next_state) gobj_change_state(dst, event_action.next_state);
|
|
2602
3027
|
let ret = -1;
|
|
2603
3028
|
try {
|
|
@@ -2611,8 +3036,10 @@
|
|
|
2611
3036
|
} catch (e2) {}
|
|
2612
3037
|
}
|
|
2613
3038
|
throw e;
|
|
3039
|
+
} finally {
|
|
3040
|
+
pop_dispatch_frame(frame);
|
|
2614
3041
|
}
|
|
2615
|
-
if (tracea && __trace_machine_format__ !== 1 && !
|
|
3042
|
+
if (tracea && __trace_machine_format__ !== 1 && !frame.destroyed) trace_machine(sprintf("<- mach(%s%s^%s), st: %s, ev: %s, ret: %d", !dst.running ? "!!" : "", gobj_gclass_name(dst), gobj_name(dst), dst.current_state.state_name, event ? event : "", is_number(ret) ? ret : 0));
|
|
2616
3043
|
__inside__--;
|
|
2617
3044
|
return ret;
|
|
2618
3045
|
}
|
|
@@ -3075,62 +3502,67 @@
|
|
|
3075
3502
|
let dl_subs = [...publisher.dl_subscriptions];
|
|
3076
3503
|
let sent_count = 0;
|
|
3077
3504
|
let ret = 0;
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
let
|
|
3082
|
-
if (
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
let
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
topublish =
|
|
3505
|
+
const frame = push_dispatch_frame(publisher, event, frame_kind_t.FRAME_PUBLICATION);
|
|
3506
|
+
try {
|
|
3507
|
+
for (let idx = 0; idx < dl_subs.length; idx++) {
|
|
3508
|
+
let subs = dl_subs[idx];
|
|
3509
|
+
if (publisher.gclass.gmt.mt_publication_pre_filter) {
|
|
3510
|
+
let topublish = publisher.gclass.gmt.mt_publication_pre_filter(publisher, subs, event, kw);
|
|
3511
|
+
if (topublish < 0) break;
|
|
3512
|
+
else if (!topublish) continue;
|
|
3513
|
+
}
|
|
3514
|
+
let subscriber = kw_get_pointer(publisher, subs, "subscriber", null, kw_flag_t.KW_REQUIRED);
|
|
3515
|
+
if (!(subscriber && !gobj_is_destroying(subscriber))) continue;
|
|
3516
|
+
let subs_flag = kw_get_int(publisher, subs, "subs_flag", 0, kw_flag_t.KW_REQUIRED);
|
|
3517
|
+
let event_ = kw_get_str(publisher, subs, "event", "", kw_flag_t.KW_REQUIRED);
|
|
3518
|
+
if (empty_string(event_) || strcasecmp(event_, event) === 0) {
|
|
3519
|
+
let __config__ = kw_get_dict(publisher, subs, "__config__", null, 0);
|
|
3520
|
+
let __global__ = kw_get_dict(publisher, subs, "__global__", null, 0);
|
|
3521
|
+
let __local__ = kw_get_dict(publisher, subs, "__local__", null, 0);
|
|
3522
|
+
let __filter__ = kw_get_dict_value(publisher, subs, "__filter__", null, 0);
|
|
3523
|
+
let event_name = subs.renamed_event;
|
|
3524
|
+
if (empty_string(event_name)) event_name = event;
|
|
3525
|
+
let topublish = 1;
|
|
3526
|
+
if (publisher.gclass.gmt.mt_publication_filter) topublish = publisher.gclass.gmt.mt_publication_filter(publisher, event, kw, subscriber);
|
|
3527
|
+
else if (json_size(__filter__) > 0) {
|
|
3528
|
+
topublish = kw_match_simple(kw, __filter__) ? 1 : 0;
|
|
3529
|
+
if (tracea) {
|
|
3530
|
+
trace_machine(sprintf("💜💜🔄%s publishing with filter, event '%s', subscriber'%s', publisher %s", topublish ? "👍" : "👎", event ? event : "", gobj_short_name(subscriber), gobj_short_name(publisher)));
|
|
3531
|
+
trace_json(__filter__);
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
if (topublish < 0) break;
|
|
3535
|
+
else if (!topublish) continue;
|
|
3536
|
+
let ev_ = gobj_event_type(subscriber, event, true);
|
|
3537
|
+
if (ev_) {
|
|
3538
|
+
if (ev_.event_flag & event_flag_t.EVF_SYSTEM_EVENT) {
|
|
3539
|
+
if (!gobj_has_event(subscriber, ev_.event_name, 0)) continue;
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
let kw2publish = kw;
|
|
3543
|
+
if (json_size(__local__) > 0 || json_size(__global__) > 0) kw2publish = json_object_update({}, kw);
|
|
3544
|
+
if (json_size(__local__) > 0) kw_pop(kw2publish, __local__);
|
|
3545
|
+
if (__config__) {}
|
|
3546
|
+
if (json_size(__global__) > 0) json_object_update(kw2publish, json_deep_copy(__global__));
|
|
3100
3547
|
if (tracea) {
|
|
3101
|
-
trace_machine(sprintf("
|
|
3102
|
-
|
|
3548
|
+
if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔄 %s (%s) %s%s", event ? event : "", event_name ? event_name : "", !subscriber.running ? "!!" : "", gobj_short_name(subscriber)));
|
|
3549
|
+
else trace_machine(sprintf("🔝🔄 mach(%s%s), st: %s, ev: %s (%s), from(%s%s)", !subscriber.running ? "!!" : "", gobj_short_name(subscriber), gobj_current_state(subscriber), event ? event : "", event_name ? event_name : "", publisher && !publisher.running ? "!!" : "", gobj_short_name(publisher)));
|
|
3550
|
+
if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw2publish)) trace_json_masked(kw2publish);
|
|
3103
3551
|
}
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
if (ev_) {
|
|
3109
|
-
if (ev_.event_flag & event_flag_t.EVF_SYSTEM_EVENT) {
|
|
3110
|
-
if (!gobj_has_event(subscriber, ev_.event_name, 0)) continue;
|
|
3552
|
+
let ret_ = gobj_send_event(subscriber, event_name, kw2publish, publisher);
|
|
3553
|
+
if (ret_ < 0 && subs_flag & subs_flag_t.__own_event__) {
|
|
3554
|
+
sent_count = -1;
|
|
3555
|
+
break;
|
|
3111
3556
|
}
|
|
3557
|
+
ret += ret_;
|
|
3558
|
+
sent_count++;
|
|
3559
|
+
if (frame.destroyed || gobj_is_destroying(publisher)) break;
|
|
3112
3560
|
}
|
|
3113
|
-
let kw2publish = kw;
|
|
3114
|
-
if (json_size(__local__) > 0 || json_size(__global__) > 0) kw2publish = json_object_update({}, kw);
|
|
3115
|
-
if (json_size(__local__) > 0) kw_pop(kw2publish, __local__);
|
|
3116
|
-
if (__config__) {}
|
|
3117
|
-
if (json_size(__global__) > 0) json_object_update(kw2publish, json_deep_copy(__global__));
|
|
3118
|
-
if (tracea) {
|
|
3119
|
-
if (__trace_machine_format__ === 1) trace_machine(sprintf("🔝🔄 %s (%s) %s%s", event ? event : "", event_name ? event_name : "", !subscriber.running ? "!!" : "", gobj_short_name(subscriber)));
|
|
3120
|
-
else trace_machine(sprintf("🔝🔄 mach(%s%s), st: %s, ev: %s (%s), from(%s%s)", !subscriber.running ? "!!" : "", gobj_short_name(subscriber), gobj_current_state(subscriber), event ? event : "", event_name ? event_name : "", publisher && !publisher.running ? "!!" : "", gobj_short_name(publisher)));
|
|
3121
|
-
if (__trace_gobj_ev_kw__(publisher) && json_object_size(kw2publish)) trace_json_masked(kw2publish);
|
|
3122
|
-
}
|
|
3123
|
-
let ret_ = gobj_send_event(subscriber, event_name, kw2publish, publisher);
|
|
3124
|
-
if (ret_ < 0 && subs_flag & subs_flag_t.__own_event__) {
|
|
3125
|
-
sent_count = -1;
|
|
3126
|
-
break;
|
|
3127
|
-
}
|
|
3128
|
-
ret += ret_;
|
|
3129
|
-
sent_count++;
|
|
3130
|
-
if (gobj_is_destroying(publisher)) break;
|
|
3131
3561
|
}
|
|
3562
|
+
} finally {
|
|
3563
|
+
pop_dispatch_frame(frame);
|
|
3132
3564
|
}
|
|
3133
|
-
if (!sent_count) {
|
|
3565
|
+
if (!sent_count && !frame.destroyed) {
|
|
3134
3566
|
if (!ev || !(ev.event_flag & event_flag_t.EVF_NO_WARN_SUBS)) log_warning(`${gobj_short_name(publisher)}: Publish event WITHOUT subscribers, ev ${event}`);
|
|
3135
3567
|
}
|
|
3136
3568
|
return ret;
|
|
@@ -3439,12 +3871,12 @@
|
|
|
3439
3871
|
"sessionkey",
|
|
3440
3872
|
"authdata"
|
|
3441
3873
|
];
|
|
3442
|
-
var SECRET_NAME_SEGMENTS =
|
|
3874
|
+
var SECRET_NAME_SEGMENTS = [
|
|
3443
3875
|
"pass",
|
|
3444
3876
|
"pin",
|
|
3445
3877
|
"otp"
|
|
3446
|
-
]
|
|
3447
|
-
var NOT_SECRET_SEGMENTS =
|
|
3878
|
+
];
|
|
3879
|
+
var NOT_SECRET_SEGMENTS = [
|
|
3448
3880
|
"endpoint",
|
|
3449
3881
|
"url",
|
|
3450
3882
|
"uri",
|
|
@@ -3467,36 +3899,130 @@
|
|
|
3467
3899
|
"expiry",
|
|
3468
3900
|
"expires",
|
|
3469
3901
|
"mode"
|
|
3470
|
-
]
|
|
3902
|
+
];
|
|
3903
|
+
function words_by_letter(list) {
|
|
3904
|
+
const by_letter = new Array(128).fill(null);
|
|
3905
|
+
for (const word of list) {
|
|
3906
|
+
const c = word.charCodeAt(0);
|
|
3907
|
+
if (!by_letter[c]) by_letter[c] = [];
|
|
3908
|
+
by_letter[c].push(word);
|
|
3909
|
+
}
|
|
3910
|
+
return by_letter;
|
|
3911
|
+
}
|
|
3912
|
+
var SECRET_PARTS_BY_LETTER = words_by_letter(SECRET_NAME_PARTS);
|
|
3913
|
+
var SECRET_JOINED_BY_LETTER = words_by_letter(SECRET_NAME_JOINED);
|
|
3914
|
+
var SECRET_SEGMENTS_BY_LETTER = words_by_letter(SECRET_NAME_SEGMENTS);
|
|
3915
|
+
var NOT_SECRET_BY_LETTER = words_by_letter(NOT_SECRET_SEGMENTS);
|
|
3916
|
+
function ascii_lower_code(code) {
|
|
3917
|
+
return code >= 65 && code <= 90 ? code + 32 : code;
|
|
3918
|
+
}
|
|
3919
|
+
function is_name_joiner_code(code) {
|
|
3920
|
+
return code === 95 || code === 45 || code === 46 || code === 32 || code === 9;
|
|
3921
|
+
}
|
|
3922
|
+
function name_segment_in(str, from, to, by_letter) {
|
|
3923
|
+
const n = to - from;
|
|
3924
|
+
if (n === 0) return false;
|
|
3925
|
+
const c0 = ascii_lower_code(str.charCodeAt(from));
|
|
3926
|
+
const words = c0 < 128 ? by_letter[c0] : null;
|
|
3927
|
+
if (!words) return false;
|
|
3928
|
+
for (let w = 0; w < words.length; w++) {
|
|
3929
|
+
const word = words[w];
|
|
3930
|
+
if (word.length !== n) continue;
|
|
3931
|
+
let i = 1;
|
|
3932
|
+
while (i < n && ascii_lower_code(str.charCodeAt(from + i)) === word.charCodeAt(i)) i++;
|
|
3933
|
+
if (i === n) return true;
|
|
3934
|
+
}
|
|
3935
|
+
return false;
|
|
3936
|
+
}
|
|
3937
|
+
function name_part_at(str, to, i, part, joined) {
|
|
3938
|
+
let j = i;
|
|
3939
|
+
let k = 0;
|
|
3940
|
+
while (k < part.length) {
|
|
3941
|
+
if (j >= to) return false;
|
|
3942
|
+
const code = str.charCodeAt(j);
|
|
3943
|
+
if (joined && k > 0 && is_name_joiner_code(code)) {
|
|
3944
|
+
j++;
|
|
3945
|
+
continue;
|
|
3946
|
+
}
|
|
3947
|
+
if (ascii_lower_code(code) !== part.charCodeAt(k)) return false;
|
|
3948
|
+
j++;
|
|
3949
|
+
k++;
|
|
3950
|
+
}
|
|
3951
|
+
return true;
|
|
3952
|
+
}
|
|
3953
|
+
function secret_name_check(str, from, to, about_wins, by_segments) {
|
|
3954
|
+
if (to - from < 3) return false;
|
|
3955
|
+
if (about_wins) {
|
|
3956
|
+
let seg = from;
|
|
3957
|
+
for (let i = from; i <= to; i++) {
|
|
3958
|
+
if (i < to && !is_name_joiner_code(str.charCodeAt(i))) continue;
|
|
3959
|
+
if (name_segment_in(str, seg, i, NOT_SECRET_BY_LETTER)) return false;
|
|
3960
|
+
seg = i + 1;
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3963
|
+
if (by_segments) {
|
|
3964
|
+
let seg = from;
|
|
3965
|
+
for (let i = from; i <= to; i++) {
|
|
3966
|
+
if (i < to && is_ascii_alnum_code(str.charCodeAt(i))) continue;
|
|
3967
|
+
if (name_segment_in(str, seg, i, SECRET_SEGMENTS_BY_LETTER)) return true;
|
|
3968
|
+
seg = i + 1;
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3971
|
+
let has_priv = false;
|
|
3972
|
+
let has_key = false;
|
|
3973
|
+
for (let i = from; i < to; i++) {
|
|
3974
|
+
const c = ascii_lower_code(str.charCodeAt(i));
|
|
3975
|
+
if (c >= 128) continue;
|
|
3976
|
+
const parts = SECRET_PARTS_BY_LETTER[c];
|
|
3977
|
+
for (let k = 0; parts && k < parts.length; k++) if (name_part_at(str, to, i, parts[k], false)) return true;
|
|
3978
|
+
const joined = SECRET_JOINED_BY_LETTER[c];
|
|
3979
|
+
for (let k = 0; joined && k < joined.length; k++) if (name_part_at(str, to, i, joined[k], true)) return true;
|
|
3980
|
+
if (c === 112 && !has_priv) has_priv = name_part_at(str, to, i, "priv", false);
|
|
3981
|
+
else if (c === 107 && !has_key) has_key = name_part_at(str, to, i, "key", false);
|
|
3982
|
+
}
|
|
3983
|
+
return has_priv && has_key;
|
|
3984
|
+
}
|
|
3471
3985
|
/************************************************************
|
|
3472
3986
|
* TRUE if `name` is the name of a secret: a password, a token,
|
|
3473
3987
|
* a key... Any case. As the C kernel's is_secret_name().
|
|
3474
3988
|
************************************************************/
|
|
3475
3989
|
function is_secret_name(name) {
|
|
3476
|
-
if (typeof name !== "string"
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
if (
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3990
|
+
if (typeof name !== "string") return false;
|
|
3991
|
+
return secret_name_check(name, 0, name.length, true, true);
|
|
3992
|
+
}
|
|
3993
|
+
var NAMES_NOW = 0;
|
|
3994
|
+
var NAMES_7_26_9 = 1;
|
|
3995
|
+
function is_secret_name_tail(str, from, to, names) {
|
|
3996
|
+
const by_segments = names === NAMES_NOW;
|
|
3997
|
+
if ((to - from) * 3 <= MASK_MAX_NAME) return secret_name_check(str, from, to, true, by_segments);
|
|
3998
|
+
let bytes = 0;
|
|
3999
|
+
let i = to;
|
|
4000
|
+
let partial = false;
|
|
4001
|
+
while (i > from) {
|
|
4002
|
+
const code = str.charCodeAt(i - 1);
|
|
4003
|
+
let n = 3;
|
|
4004
|
+
let units = 1;
|
|
4005
|
+
if (code < 128) n = 1;
|
|
4006
|
+
else if (code < 2048) n = 2;
|
|
4007
|
+
else if (code >= 56320 && code <= 57343 && i - 2 >= from) {
|
|
4008
|
+
const high = str.charCodeAt(i - 2);
|
|
4009
|
+
if (high >= 55296 && high <= 56319) {
|
|
4010
|
+
n = 4;
|
|
4011
|
+
units = 2;
|
|
4012
|
+
}
|
|
3487
4013
|
}
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
let joined = lower.replace(/[_\-. \t]/g, "");
|
|
3491
|
-
for (const part of SECRET_NAME_JOINED) if (joined.indexOf(part) >= 0) {
|
|
3492
|
-
hit = true;
|
|
4014
|
+
if (bytes + n > MASK_MAX_NAME) {
|
|
4015
|
+
partial = bytes < MASK_MAX_NAME;
|
|
3493
4016
|
break;
|
|
3494
4017
|
}
|
|
4018
|
+
bytes += n;
|
|
4019
|
+
i -= units;
|
|
3495
4020
|
}
|
|
3496
|
-
if (
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
4021
|
+
if (partial) {
|
|
4022
|
+
const name = "" + str.substring(i, to);
|
|
4023
|
+
return secret_name_check(name, 0, name.length, true, by_segments);
|
|
4024
|
+
}
|
|
4025
|
+
return secret_name_check(str, i, to, true, by_segments);
|
|
3500
4026
|
}
|
|
3501
4027
|
/************************************************************
|
|
3502
4028
|
* Where an unquoted secret value that begins at `p` ends: at
|
|
@@ -3527,10 +4053,11 @@
|
|
|
3527
4053
|
* jwt_len() / scheme_credential(), the shapes the agent's audit
|
|
3528
4054
|
* record redacts, and the schemes of an HTTP Authorization:
|
|
3529
4055
|
* - a JWT or a JWE: "eyJ" (the base64url of '{"') at the start
|
|
3530
|
-
* of a word, base64url, and a '.' after it -- three
|
|
3531
|
-
* joined by '.' (a JWS), five (a JWE), or fewer when a cap
|
|
3532
|
-
* it; the dots at the end of the run are not its own (a JWT
|
|
3533
|
-
* ends a sentence: "... eyJ.eyJ.sig.")
|
|
4056
|
+
* of a word, base64url, and a '.' of its own after it -- three
|
|
4057
|
+
* parts joined by '.' (a JWS), five (a JWE), or fewer when a cap
|
|
4058
|
+
* cut it; the dots at the end of the run are not its own (a JWT
|
|
4059
|
+
* ends a sentence: "... eyJ.eyJ.sig."), so a run whose only
|
|
4060
|
+
* dots end it is a header and no JWT ("eyJhIjoxfQ.");
|
|
3534
4061
|
* - the credential after the scheme word "Bearer" or "Basic"
|
|
3535
4062
|
* (any case, a word of its own): scheme_credential().
|
|
3536
4063
|
************************************************************/
|
|
@@ -3563,7 +4090,7 @@
|
|
|
3563
4090
|
let e = p;
|
|
3564
4091
|
let dotted = false;
|
|
3565
4092
|
while (e < str.length && (is_base64url_code(str.charCodeAt(e)) || str[e] === ".")) {
|
|
3566
|
-
if (str[e] === ".") dotted = true;
|
|
4093
|
+
if (e > p && str[e] !== "." && str[e - 1] === ".") dotted = true;
|
|
3567
4094
|
e++;
|
|
3568
4095
|
}
|
|
3569
4096
|
if (!dotted) return 0;
|
|
@@ -3671,7 +4198,7 @@
|
|
|
3671
4198
|
if (c === "b" || c === "B") return scheme_credential(str, p);
|
|
3672
4199
|
return [0, 0];
|
|
3673
4200
|
}
|
|
3674
|
-
function
|
|
4201
|
+
function shape_len_js_7_26_20(str, p) {
|
|
3675
4202
|
const c = str[p];
|
|
3676
4203
|
if (c === "e") {
|
|
3677
4204
|
if (str.length - p < 3 || str[p + 1] !== "y" || str[p + 2] !== "J") return [0, 0];
|
|
@@ -3759,7 +4286,12 @@
|
|
|
3759
4286
|
function mark_range(marks, from, to) {
|
|
3760
4287
|
for (let i = from; i < to; i++) marks[i] = 1;
|
|
3761
4288
|
}
|
|
3762
|
-
|
|
4289
|
+
var READ_NOW = 0;
|
|
4290
|
+
var READ_AS_GOBJ_JS_7_26_20 = 1;
|
|
4291
|
+
var READ_AS_7_26_9 = 2;
|
|
4292
|
+
function mark_params(str, value_is_secret, reading, marks, judged) {
|
|
4293
|
+
const names = reading === READ_AS_7_26_9 ? NAMES_7_26_9 : NAMES_NOW;
|
|
4294
|
+
let not_7_26_9 = false;
|
|
3763
4295
|
const is_blank_or_end = (i) => i >= str.length || str[i] === " " || str[i] === " " || str[i] === "\0";
|
|
3764
4296
|
let outer = "";
|
|
3765
4297
|
let word = 0;
|
|
@@ -3775,8 +4307,8 @@
|
|
|
3775
4307
|
if (!outer && (p === 0 || str[p - 1] === " " || str[p - 1] === " " || str[p - 1] === "=")) outer = c;
|
|
3776
4308
|
else if (c === outer && is_blank_or_end(p + 1)) outer = "";
|
|
3777
4309
|
}
|
|
3778
|
-
if (
|
|
3779
|
-
const [offset, n] =
|
|
4310
|
+
if (reading === READ_AS_GOBJ_JS_7_26_20 && (c === "e" || c === "b" || c === "B")) {
|
|
4311
|
+
const [offset, n] = shape_len_js_7_26_20(str, p);
|
|
3780
4312
|
if (n) {
|
|
3781
4313
|
p += offset + n;
|
|
3782
4314
|
word = p;
|
|
@@ -3787,10 +4319,12 @@
|
|
|
3787
4319
|
p++;
|
|
3788
4320
|
continue;
|
|
3789
4321
|
}
|
|
3790
|
-
const name_from =
|
|
3791
|
-
const name = str.substring(name_from, p);
|
|
4322
|
+
const name_from = word;
|
|
3792
4323
|
word = p + 1;
|
|
3793
|
-
|
|
4324
|
+
const secret = is_secret_name_tail(str, name_from, p, names);
|
|
4325
|
+
if (secret && names === NAMES_NOW && !is_secret_name_tail(str, name_from, p, NAMES_7_26_9)) not_7_26_9 = true;
|
|
4326
|
+
if (!(secret || value_is_secret && p - name_from === 5 && ascii_case_equal(str, name_from, "value"))) {
|
|
4327
|
+
if (judged && query_name_from(str, p) === name_from) judged[p] = 1;
|
|
3794
4328
|
p++;
|
|
3795
4329
|
continue;
|
|
3796
4330
|
}
|
|
@@ -3806,11 +4340,79 @@
|
|
|
3806
4340
|
p = end;
|
|
3807
4341
|
word = p;
|
|
3808
4342
|
}
|
|
4343
|
+
return not_7_26_9;
|
|
4344
|
+
}
|
|
4345
|
+
function has_shape_js_7_26_20(str) {
|
|
4346
|
+
for (let p = 0; p < str.length; p++) {
|
|
4347
|
+
const code = str.charCodeAt(p);
|
|
4348
|
+
if ((code === 101 || code === 98 || code === 66) && shape_len_js_7_26_20(str, p)[1]) return true;
|
|
4349
|
+
}
|
|
4350
|
+
return false;
|
|
4351
|
+
}
|
|
4352
|
+
function stop_table(chars) {
|
|
4353
|
+
const table = /* @__PURE__ */ new Uint8Array(128);
|
|
4354
|
+
for (const c of chars + "\r\n\0") table[c.charCodeAt(0)] = 1;
|
|
4355
|
+
return table;
|
|
4356
|
+
}
|
|
4357
|
+
var PARAM_VALUE_STOPS = stop_table("&; ,\"'<>");
|
|
4358
|
+
var QUOTE_STOPS = {
|
|
4359
|
+
"\"": stop_table("\""),
|
|
4360
|
+
"'": stop_table("'")
|
|
4361
|
+
};
|
|
4362
|
+
function mark_run(str, p, stops, marks) {
|
|
4363
|
+
let e = p;
|
|
4364
|
+
while (e < str.length) {
|
|
4365
|
+
const code = str.charCodeAt(e);
|
|
4366
|
+
if (code < 128 && stops[code]) break;
|
|
4367
|
+
e++;
|
|
4368
|
+
}
|
|
4369
|
+
mark_range(marks, p, e);
|
|
4370
|
+
return e;
|
|
4371
|
+
}
|
|
4372
|
+
function mark_scheme_value(str, v, stops, marks) {
|
|
4373
|
+
const n = scheme_word_len(str, v);
|
|
4374
|
+
if (!n) return -1;
|
|
4375
|
+
let w = v + n;
|
|
4376
|
+
while (w < str.length && (str[w] === " " || str[w] === " ")) w++;
|
|
4377
|
+
mark_range(marks, v, w);
|
|
4378
|
+
if (w < str.length && (str[w] === "\"" || str[w] === "'")) {
|
|
4379
|
+
const e = colon_value_end(str, w);
|
|
4380
|
+
mark_range(marks, w, e);
|
|
4381
|
+
return e;
|
|
4382
|
+
}
|
|
4383
|
+
return mark_run(str, w, stops, marks);
|
|
4384
|
+
}
|
|
4385
|
+
function is_name_char_code(code) {
|
|
4386
|
+
return is_ascii_alnum_code(code) || code === 95 || code === 45 || code === 46;
|
|
4387
|
+
}
|
|
4388
|
+
function query_name_from(str, eq) {
|
|
4389
|
+
let n = eq;
|
|
4390
|
+
while (n > 0 && eq - n < MASK_MAX_NAME && is_name_char_code(str.charCodeAt(n - 1))) n--;
|
|
4391
|
+
return n;
|
|
4392
|
+
}
|
|
4393
|
+
function mark_query_params(str, marks, judged) {
|
|
4394
|
+
let frontier = 0;
|
|
4395
|
+
for (let p = 1; p < str.length; p++) {
|
|
4396
|
+
if (p < frontier) {
|
|
4397
|
+
p = frontier - 1;
|
|
4398
|
+
continue;
|
|
4399
|
+
}
|
|
4400
|
+
if (str.charCodeAt(p) !== 61) continue;
|
|
4401
|
+
if (judged[p]) continue;
|
|
4402
|
+
const n = query_name_from(str, p);
|
|
4403
|
+
if (n === p || !secret_name_check(str, n, p, true, true)) continue;
|
|
4404
|
+
const v = p + 1;
|
|
4405
|
+
if (v < str.length && (str[v] === "\"" || str[v] === "'")) frontier = mark_run(str, v + 1, QUOTE_STOPS[str[v]], marks);
|
|
4406
|
+
else {
|
|
4407
|
+
mark_scheme_value(str, v, PARAM_VALUE_STOPS, marks);
|
|
4408
|
+
frontier = mark_run(str, v, PARAM_VALUE_STOPS, marks);
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
3809
4411
|
}
|
|
3810
4412
|
function mark_shapes(str, marks) {
|
|
3811
4413
|
for (let p = 0; p < str.length; p++) {
|
|
3812
|
-
const
|
|
3813
|
-
if (
|
|
4414
|
+
const code = str.charCodeAt(p);
|
|
4415
|
+
if (code !== 101 && code !== 98 && code !== 66) continue;
|
|
3814
4416
|
const [offset, n] = shape_len(str, p);
|
|
3815
4417
|
if (n) mark_range(marks, p + offset, p + offset + n);
|
|
3816
4418
|
}
|
|
@@ -3819,17 +4421,17 @@
|
|
|
3819
4421
|
let word = 0;
|
|
3820
4422
|
let p = 0;
|
|
3821
4423
|
while (p < str.length) {
|
|
3822
|
-
const
|
|
3823
|
-
if (
|
|
4424
|
+
const code = str.charCodeAt(p);
|
|
4425
|
+
if (code === 32 || code === 9 || code === 0 || code === 61) {
|
|
3824
4426
|
p++;
|
|
3825
4427
|
word = p;
|
|
3826
4428
|
continue;
|
|
3827
4429
|
}
|
|
3828
|
-
if (
|
|
4430
|
+
if (code !== 58) {
|
|
3829
4431
|
p++;
|
|
3830
4432
|
continue;
|
|
3831
4433
|
}
|
|
3832
|
-
if (!
|
|
4434
|
+
if (!is_secret_name_tail(str, word, p, NAMES_NOW)) {
|
|
3833
4435
|
p++;
|
|
3834
4436
|
word = p;
|
|
3835
4437
|
continue;
|
|
@@ -3844,31 +4446,50 @@
|
|
|
3844
4446
|
word = p;
|
|
3845
4447
|
}
|
|
3846
4448
|
}
|
|
4449
|
+
function inline_value_is_secret(str, names) {
|
|
4450
|
+
let p = str.indexOf("attribute=");
|
|
4451
|
+
while (p >= 0) {
|
|
4452
|
+
if (p === 0 || str[p - 1] === " " || str[p - 1] === " ") {
|
|
4453
|
+
let v = p + 10;
|
|
4454
|
+
if (v < str.length && (str[v] === "\"" || str[v] === "'")) v++;
|
|
4455
|
+
let e = v;
|
|
4456
|
+
while (e < str.length && " \"'\0".indexOf(str[e]) < 0) e++;
|
|
4457
|
+
if (is_secret_name_tail(str, v, e, names)) return true;
|
|
4458
|
+
}
|
|
4459
|
+
p = str.indexOf("attribute=", p + 1);
|
|
4460
|
+
}
|
|
4461
|
+
return false;
|
|
4462
|
+
}
|
|
4463
|
+
function mark_inline_secrets(str, marks) {
|
|
4464
|
+
const value_is_secret = inline_value_is_secret(str, NAMES_NOW);
|
|
4465
|
+
const value_is_secret_7_26_9 = inline_value_is_secret(str, NAMES_7_26_9);
|
|
4466
|
+
const judged = new Uint8Array(str.length);
|
|
4467
|
+
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);
|
|
4468
|
+
if (has_shape_js_7_26_20(str)) mark_params(str, value_is_secret, READ_AS_GOBJ_JS_7_26_20, marks, null);
|
|
4469
|
+
mark_query_params(str, marks, judged);
|
|
4470
|
+
mark_shapes(str, marks);
|
|
4471
|
+
mark_labels(str, marks);
|
|
4472
|
+
}
|
|
3847
4473
|
/************************************************************
|
|
3848
4474
|
* A text (a command line) with the secrets that can be told
|
|
3849
4475
|
* written as "********" (each run of them as one), the rest as it
|
|
3850
4476
|
* is: the value of every "name=value" whose name is a secret's,
|
|
3851
4477
|
* quoted or not (and the "value" of a write-attr whose attribute
|
|
3852
|
-
* names a secret)
|
|
3853
|
-
*
|
|
3854
|
-
*
|
|
3855
|
-
*
|
|
3856
|
-
*
|
|
3857
|
-
*
|
|
4478
|
+
* names a secret) -- the name is the word before the '=', and also
|
|
4479
|
+
* the run of name characters before it, as in a query string; the
|
|
4480
|
+
* same for a "name: value", its name in quotes or not (a json, a
|
|
4481
|
+
* header, a label: "password": x, Authorization: Basic x, bearer:
|
|
4482
|
+
* tok); and a JWT or the credential after "Bearer " or "Basic ",
|
|
4483
|
+
* wherever they are, whatever names them. Each rule judges the text
|
|
4484
|
+
* as it came. Return null when there was nothing to mask. As the C
|
|
4485
|
+
* kernel's mask_secrets_inline().
|
|
3858
4486
|
************************************************************/
|
|
3859
4487
|
function mask_secrets_inline(str) {
|
|
3860
4488
|
if (typeof str !== "string") return null;
|
|
3861
4489
|
if (str.indexOf("=") < 0 && str.indexOf(":") < 0 && str.indexOf("eyJ") < 0 && !/bearer|basic/i.test(str)) return null;
|
|
3862
4490
|
if (str.length > MASK_MAX_BYTES) return MASK_TOO_LARGE;
|
|
3863
|
-
let value_is_secret = false;
|
|
3864
|
-
let re_attr = /(^|[ \t])attribute=["']?([^ \t"'\u0000]*)/g;
|
|
3865
|
-
let m;
|
|
3866
|
-
while ((m = re_attr.exec(str)) !== null) if (is_secret_name(m[2].slice(-128))) value_is_secret = true;
|
|
3867
4491
|
const marks = new Uint8Array(str.length);
|
|
3868
|
-
|
|
3869
|
-
mark_params(str, value_is_secret, false, marks);
|
|
3870
|
-
mark_shapes(str, marks);
|
|
3871
|
-
mark_labels(str, marks);
|
|
4492
|
+
mark_inline_secrets(str, marks);
|
|
3872
4493
|
let parts = [];
|
|
3873
4494
|
let changed = false;
|
|
3874
4495
|
let i = 0;
|
|
@@ -3952,7 +4573,12 @@
|
|
|
3952
4573
|
if (truncated) result.push(MASK_TOO_LARGE);
|
|
3953
4574
|
} else {
|
|
3954
4575
|
result = Object.create(Object.getPrototypeOf(jn));
|
|
3955
|
-
let value_is_secret =
|
|
4576
|
+
let value_is_secret = false;
|
|
4577
|
+
if (typeof jn.attribute === "string") {
|
|
4578
|
+
let nul = jn.attribute.indexOf("\0");
|
|
4579
|
+
let attribute = nul >= 0 ? jn.attribute.substring(0, nul) : jn.attribute;
|
|
4580
|
+
value_is_secret = is_secret_name_tail(attribute, 0, attribute.length, NAMES_NOW);
|
|
4581
|
+
}
|
|
3956
4582
|
for (const key in jn) {
|
|
3957
4583
|
if (!Object.prototype.hasOwnProperty.call(jn, key)) continue;
|
|
3958
4584
|
if (budget.left <= 0) {
|
|
@@ -3962,7 +4588,7 @@
|
|
|
3962
4588
|
budget.left -= 1 + key.length;
|
|
3963
4589
|
let value = jn[key];
|
|
3964
4590
|
let shown;
|
|
3965
|
-
if ((
|
|
4591
|
+
if ((is_secret_name_tail(key, 0, key.length, NAMES_NOW) || value_is_secret && key === "value") && value !== void 0 && value !== null && value !== "") shown = "********";
|
|
3966
4592
|
else shown = _json_mask_secrets(value, memo, depth + 1, budget);
|
|
3967
4593
|
if (shown !== value) changed = true;
|
|
3968
4594
|
set_own_key(result, key, shown);
|
|
@@ -7111,8 +7737,12 @@
|
|
|
7111
7737
|
***************************************************************/
|
|
7112
7738
|
function mt_create$2(gobj) {
|
|
7113
7739
|
let priv = gobj.priv;
|
|
7114
|
-
|
|
7740
|
+
let subscriber = gobj_read_pointer_attr(gobj, "subscriber");
|
|
7115
7741
|
if (subscriber) gobj_subscribe_event(gobj, null, {}, subscriber);
|
|
7742
|
+
else if (gobj_is_pure_child(gobj)) {
|
|
7743
|
+
subscriber = gobj_parent(gobj);
|
|
7744
|
+
gobj_subscribe_event(gobj, null, {}, subscriber);
|
|
7745
|
+
}
|
|
7116
7746
|
priv.periodic = gobj_read_bool_attr(gobj, "periodic");
|
|
7117
7747
|
priv.msec = gobj_read_integer_attr(gobj, "msec");
|
|
7118
7748
|
}
|
|
@@ -7169,8 +7799,7 @@
|
|
|
7169
7799
|
gobj_send_event(gobj, "EV_TIMEOUT", {}, gobj);
|
|
7170
7800
|
}, priv.msec);
|
|
7171
7801
|
else priv.timer_id = -1;
|
|
7172
|
-
|
|
7173
|
-
else gobj_publish_event(gobj, ev, {});
|
|
7802
|
+
gobj_publish_event(gobj, ev, {});
|
|
7174
7803
|
if (!priv.periodic && priv.timer_id === -1) {
|
|
7175
7804
|
if (gobj_is_running(gobj)) gobj_stop(gobj);
|
|
7176
7805
|
}
|
|
@@ -7217,6 +7846,15 @@
|
|
|
7217
7846
|
* Helpers
|
|
7218
7847
|
***************************/
|
|
7219
7848
|
/***************************************************************************
|
|
7849
|
+
* A number of milliseconds as the integer `msec` holds it: C takes an
|
|
7850
|
+
* integer, and a time computed in JS can carry a float error (0.3 * 1000
|
|
7851
|
+
* is 300.00000000000006, which an integer attr refuses). Anything that is
|
|
7852
|
+
* not a number goes as it is, to be refused loudly by the attr.
|
|
7853
|
+
***************************************************************************/
|
|
7854
|
+
function whole_msec(msec) {
|
|
7855
|
+
return typeof msec === "number" && Number.isFinite(msec) ? Math.round(msec) : msec;
|
|
7856
|
+
}
|
|
7857
|
+
/***************************************************************************
|
|
7220
7858
|
* Set timeout
|
|
7221
7859
|
***************************************************************************/
|
|
7222
7860
|
function set_timeout(gobj, msec) {
|
|
@@ -7229,7 +7867,7 @@
|
|
|
7229
7867
|
return -1;
|
|
7230
7868
|
}
|
|
7231
7869
|
gobj_write_bool_attr(gobj, "periodic", false);
|
|
7232
|
-
gobj_write_integer_attr(gobj, "msec", msec);
|
|
7870
|
+
gobj_write_integer_attr(gobj, "msec", whole_msec(msec));
|
|
7233
7871
|
}
|
|
7234
7872
|
/***************************************************************************
|
|
7235
7873
|
* Set periodic timeout
|
|
@@ -7244,7 +7882,7 @@
|
|
|
7244
7882
|
return -1;
|
|
7245
7883
|
}
|
|
7246
7884
|
gobj_write_bool_attr(gobj, "periodic", true);
|
|
7247
|
-
gobj_write_integer_attr(gobj, "msec", msec);
|
|
7885
|
+
gobj_write_integer_attr(gobj, "msec", whole_msec(msec));
|
|
7248
7886
|
}
|
|
7249
7887
|
/***************************************************************************
|
|
7250
7888
|
* Clear timeout
|
|
@@ -7631,8 +8269,12 @@
|
|
|
7631
8269
|
gobj_write_str_attr(gobj, "wanted_yuno_name", priv.remote_yuno_name);
|
|
7632
8270
|
gobj_write_str_attr(gobj, "wanted_yuno_role", priv.remote_yuno_role);
|
|
7633
8271
|
gobj_write_str_attr(gobj, "wanted_yuno_service", priv.remote_yuno_service);
|
|
7634
|
-
|
|
8272
|
+
let subscriber = gobj_read_pointer_attr(gobj, "subscriber");
|
|
7635
8273
|
if (subscriber) gobj_subscribe_event(gobj, null, {}, subscriber);
|
|
8274
|
+
else if (gobj_is_pure_child(gobj)) {
|
|
8275
|
+
subscriber = gobj_parent(gobj);
|
|
8276
|
+
gobj_subscribe_event(gobj, null, {}, subscriber);
|
|
8277
|
+
}
|
|
7636
8278
|
}
|
|
7637
8279
|
/***************************************************************
|
|
7638
8280
|
* Framework Method: Writing
|
|
@@ -7857,6 +8499,27 @@
|
|
|
7857
8499
|
}
|
|
7858
8500
|
}
|
|
7859
8501
|
/***************************************************************
|
|
8502
|
+
* A text of the server -- a frame, the name of an event, of a
|
|
8503
|
+
* service, of a role -- as a log shows it: masked, then capped on a
|
|
8504
|
+
* whole character (capped first, a credential the cap cut would
|
|
8505
|
+
* show its first characters). As the C kernel shows the name of an
|
|
8506
|
+
* event that is not public (mask_secrets_inline_capped()).
|
|
8507
|
+
***************************************************************/
|
|
8508
|
+
var PEER_NAME_SHOWN = 64;
|
|
8509
|
+
var PEER_FRAME_SHOWN = 256;
|
|
8510
|
+
function peer_text_shown(text, max) {
|
|
8511
|
+
let s = String(text);
|
|
8512
|
+
let masked = mask_secrets_inline(s);
|
|
8513
|
+
if (masked !== null) s = masked;
|
|
8514
|
+
if (s.length > max) {
|
|
8515
|
+
let n = max;
|
|
8516
|
+
let code = s.charCodeAt(n);
|
|
8517
|
+
if (code >= 56320 && code <= 57343) n--;
|
|
8518
|
+
s = s.substring(0, n);
|
|
8519
|
+
}
|
|
8520
|
+
return s;
|
|
8521
|
+
}
|
|
8522
|
+
/***************************************************************
|
|
7860
8523
|
* Trace intra event
|
|
7861
8524
|
***************************************************************/
|
|
7862
8525
|
function trace_inter_event(gobj, prefix, iev) {
|
|
@@ -7979,7 +8642,8 @@
|
|
|
7979
8642
|
try {
|
|
7980
8643
|
x = JSON.parse(data);
|
|
7981
8644
|
} catch (e) {
|
|
7982
|
-
|
|
8645
|
+
let at = /position (\d+)/.exec(String(e && e.message));
|
|
8646
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event json: frame is not json${at ? ", at position " + at[1] : ""}, ${String(data).length} characters`);
|
|
7983
8647
|
return null;
|
|
7984
8648
|
}
|
|
7985
8649
|
if (!(x instanceof Object)) {
|
|
@@ -8064,7 +8728,7 @@
|
|
|
8064
8728
|
let url = kw.url;
|
|
8065
8729
|
if (kw.ws_seq !== void 0 && kw.ws_seq !== priv.ws_seq) return 0;
|
|
8066
8730
|
set_remote_log_functions();
|
|
8067
|
-
log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
|
|
8731
|
+
log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${kw.code}, Reason: "${peer_text_shown(kw.reason, PEER_FRAME_SHOWN)}", Clean: ${kw.was_clean})`);
|
|
8068
8732
|
if (priv.websocket) {
|
|
8069
8733
|
priv.websocket.onopen = null;
|
|
8070
8734
|
priv.websocket.onmessage = null;
|
|
@@ -8149,7 +8813,7 @@
|
|
|
8149
8813
|
let services_roles = kw_get_dict_value(gobj, kw, "services_roles", {});
|
|
8150
8814
|
if (result < 0) {
|
|
8151
8815
|
close_websocket(gobj);
|
|
8152
|
-
|
|
8816
|
+
gobj_publish_event(gobj, "EV_ON_ID_NAK", {
|
|
8153
8817
|
"url": gobj_read_str_attr(gobj, "url"),
|
|
8154
8818
|
"result": result,
|
|
8155
8819
|
"comment": comment,
|
|
@@ -8157,24 +8821,20 @@
|
|
|
8157
8821
|
"remote_yuno_name": src_yuno,
|
|
8158
8822
|
"remote_yuno_role": src_role,
|
|
8159
8823
|
"remote_yuno_service": src_service
|
|
8160
|
-
};
|
|
8161
|
-
if (gobj_is_pure_child(gobj)) gobj_send_event(gobj_parent(gobj), "EV_ON_ID_NAK", kw_nak, gobj);
|
|
8162
|
-
else gobj_publish_event(gobj, "EV_ON_ID_NAK", kw_nak);
|
|
8824
|
+
});
|
|
8163
8825
|
} else {
|
|
8164
8826
|
gobj_change_state(gobj, "ST_SESSION");
|
|
8165
8827
|
priv.inside_on_open = true;
|
|
8166
8828
|
priv.retry_ms = 0;
|
|
8167
8829
|
if (!priv.inform_on_close) {
|
|
8168
8830
|
priv.inform_on_close = true;
|
|
8169
|
-
|
|
8831
|
+
gobj_publish_event(gobj, "EV_ON_OPEN", {
|
|
8170
8832
|
"username": username_,
|
|
8171
8833
|
"remote_yuno_name": src_yuno,
|
|
8172
8834
|
"remote_yuno_role": src_role,
|
|
8173
8835
|
"remote_yuno_service": src_service,
|
|
8174
8836
|
"services_roles": services_roles
|
|
8175
|
-
};
|
|
8176
|
-
if (gobj_is_pure_child(gobj)) gobj_send_event(gobj_parent(gobj), "EV_ON_OPEN", kw_on_open, gobj);
|
|
8177
|
-
else gobj_publish_event(gobj, "EV_ON_OPEN", kw_on_open);
|
|
8837
|
+
});
|
|
8178
8838
|
}
|
|
8179
8839
|
priv.inside_on_open = false;
|
|
8180
8840
|
resend_subscriptions(gobj);
|
|
@@ -8188,7 +8848,7 @@
|
|
|
8188
8848
|
let url = gobj.priv.url;
|
|
8189
8849
|
let iev_msg = iev_create_from_json(gobj, kw.data);
|
|
8190
8850
|
if (!iev_msg) {
|
|
8191
|
-
log_warning(`${gobj_short_name(gobj)}: frame dropped from ${url}: ${
|
|
8851
|
+
log_warning(`${gobj_short_name(gobj)}: frame dropped from ${url}: ${peer_text_shown(kw.data, PEER_FRAME_SHOWN)}`);
|
|
8192
8852
|
return -1;
|
|
8193
8853
|
}
|
|
8194
8854
|
if (is_traffic_tracing(gobj)) {
|
|
@@ -8203,7 +8863,7 @@
|
|
|
8203
8863
|
if (gobj_current_state(gobj) !== "ST_SESSION") {
|
|
8204
8864
|
if (gobj_has_event(gobj, iev_event, event_flag_t.EVF_PUBLIC_EVENT)) {
|
|
8205
8865
|
if (!(gobj_send_event(gobj, iev_event, iev_kw, gobj) < 0)) return 0;
|
|
8206
|
-
} else log_error(`${gobj_short_name(gobj)}: event UNKNOWN in not-session state ${iev_event}`);
|
|
8866
|
+
} else log_error(`${gobj_short_name(gobj)}: event UNKNOWN in not-session state ${peer_text_shown(iev_event, PEER_NAME_SHOWN)}`);
|
|
8207
8867
|
close_websocket(gobj);
|
|
8208
8868
|
return -1;
|
|
8209
8869
|
}
|
|
@@ -8212,16 +8872,16 @@
|
|
|
8212
8872
|
let event_id = msg_iev_get_stack(gobj, iev_kw, IEVENT_STACK_ID);
|
|
8213
8873
|
let iev_dst_role = kw_get_str(gobj, event_id, "dst_role", "");
|
|
8214
8874
|
if (iev_dst_role.toLowerCase() !== gobj_yuno_role().toLowerCase()) {
|
|
8215
|
-
log_error(`"It's not my role, dst_role: ${iev_dst_role}, my_role: ${gobj_yuno_role()}`);
|
|
8875
|
+
log_error(`"It's not my role, dst_role: ${peer_text_shown(iev_dst_role, PEER_NAME_SHOWN)}, my_role: ${gobj_yuno_role()}`);
|
|
8216
8876
|
return 0;
|
|
8217
8877
|
}
|
|
8218
8878
|
let iev_dst_service = kw_get_str(gobj, event_id, "dst_service", "");
|
|
8219
8879
|
if (msg_type === "__subscribing__") {
|
|
8220
|
-
log_warning(`${gobj_short_name(gobj)}: subscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
|
|
8880
|
+
log_warning(`${gobj_short_name(gobj)}: subscription event ignored, I'm client (service: ${peer_text_shown(iev_dst_service, PEER_NAME_SHOWN)}, event: ${peer_text_shown(iev_event, PEER_NAME_SHOWN)})`);
|
|
8221
8881
|
return -1;
|
|
8222
8882
|
}
|
|
8223
8883
|
if (msg_type === "__unsubscribing__") {
|
|
8224
|
-
log_warning(`${gobj_short_name(gobj)}: unsubscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
|
|
8884
|
+
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)})`);
|
|
8225
8885
|
return -1;
|
|
8226
8886
|
}
|
|
8227
8887
|
if (gobj_has_event(gobj, iev_event, event_flag_t.EVF_PUBLIC_EVENT)) {
|
|
@@ -8231,18 +8891,17 @@
|
|
|
8231
8891
|
if (!empty_string(iev_dst_service)) {
|
|
8232
8892
|
let gobj_service = gobj_find_service(iev_dst_service, false);
|
|
8233
8893
|
if (!gobj_service) {
|
|
8234
|
-
log_warning(`${gobj_short_name(gobj)}: event for a service that is gone, DROPPED: service '${iev_dst_service}', ev '${iev_event}'`);
|
|
8894
|
+
log_warning(`${gobj_short_name(gobj)}: event for a service that is gone, DROPPED: service '${peer_text_shown(iev_dst_service, PEER_NAME_SHOWN)}', ev '${peer_text_shown(iev_event, PEER_NAME_SHOWN)}'`);
|
|
8235
8895
|
return 0;
|
|
8236
8896
|
}
|
|
8237
8897
|
if (!gobj_has_event(gobj_service, iev_event, event_flag_t.EVF_PUBLIC_EVENT)) {
|
|
8238
|
-
log_error(`${gobj_short_name(gobj)}: Service found but no event or not public, service '${gobj_short_name(gobj_service)}', ev '${iev_event}'`);
|
|
8898
|
+
log_error(`${gobj_short_name(gobj)}: Service found but no event or not public, service '${gobj_short_name(gobj_service)}', ev '${peer_text_shown(iev_event, PEER_NAME_SHOWN)}'`);
|
|
8239
8899
|
return -1;
|
|
8240
8900
|
}
|
|
8241
8901
|
gobj_send_event(gobj_service, iev_event, iev_kw, gobj);
|
|
8242
8902
|
return 0;
|
|
8243
8903
|
}
|
|
8244
|
-
|
|
8245
|
-
else gobj_publish_event(gobj, iev_event, iev_kw);
|
|
8904
|
+
gobj_publish_event(gobj, iev_event, iev_kw);
|
|
8246
8905
|
return 0;
|
|
8247
8906
|
}
|
|
8248
8907
|
/***************************************************************************
|
|
@@ -8404,6 +9063,8 @@
|
|
|
8404
9063
|
exports.clean_name = clean_name;
|
|
8405
9064
|
exports.clear_timeout = clear_timeout;
|
|
8406
9065
|
exports.cmp_two_simple_json = cmp_two_simple_json;
|
|
9066
|
+
exports.command_parameter_from_json = command_parameter_from_json;
|
|
9067
|
+
exports.command_parameter_from_text = command_parameter_from_text;
|
|
8407
9068
|
exports.command_parser = command_parser;
|
|
8408
9069
|
exports.createElement2 = createElement2;
|
|
8409
9070
|
exports.createOneHtml = createOneHtml;
|