@contrast/agent 4.5.1 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/bin/VERSION +1 -1
  2. package/bin/linux/contrast-service +0 -0
  3. package/bin/mac/contrast-service +0 -0
  4. package/bin/windows/contrast-service.exe +0 -0
  5. package/lib/assess/membrane/deserialization-membrane.js +4 -5
  6. package/lib/assess/membrane/source-membrane.js +16 -33
  7. package/lib/assess/models/call-context.js +1 -1
  8. package/lib/assess/policy/propagators.json +19 -21
  9. package/lib/assess/policy/rules.json +7 -2
  10. package/lib/assess/policy/signatures.json +42 -0
  11. package/lib/assess/policy/util.js +2 -1
  12. package/lib/assess/propagators/JSON/parse.js +1 -1
  13. package/lib/assess/propagators/JSON/stringify.js +3 -3
  14. package/lib/assess/propagators/array-prototype-join.js +7 -8
  15. package/lib/assess/propagators/common.js +7 -5
  16. package/lib/assess/propagators/dustjs/escape-html.js +22 -0
  17. package/lib/assess/propagators/dustjs/escape-js.js +22 -0
  18. package/lib/assess/propagators/encode-uri/encode-uri-component.js +22 -0
  19. package/lib/assess/propagators/encode-uri/encode-uri.js +22 -0
  20. package/lib/assess/propagators/handlebars-escape-expresssion.js +1 -1
  21. package/lib/assess/propagators/index.js +0 -2
  22. package/lib/assess/propagators/joi/boolean.js +1 -1
  23. package/lib/assess/propagators/joi/expression.js +1 -1
  24. package/lib/assess/propagators/joi/number.js +1 -1
  25. package/lib/assess/propagators/joi/string-base.js +1 -1
  26. package/lib/assess/propagators/joi/string-schema.js +12 -13
  27. package/lib/assess/propagators/joi/values.js +37 -22
  28. package/lib/assess/propagators/manager.js +12 -10
  29. package/lib/assess/propagators/mongoose/helpers.js +20 -0
  30. package/lib/assess/propagators/mongoose/index.js +18 -0
  31. package/lib/assess/propagators/mongoose/map.js +74 -0
  32. package/lib/assess/propagators/mongoose/string.js +104 -0
  33. package/lib/assess/propagators/mustache/escape.js +22 -0
  34. package/lib/assess/propagators/number.js +54 -0
  35. package/lib/assess/propagators/object.js +6 -7
  36. package/lib/assess/propagators/path/basename.js +14 -13
  37. package/lib/assess/propagators/path/common.js +156 -47
  38. package/lib/assess/propagators/path/dirname.js +14 -13
  39. package/lib/assess/propagators/path/extname.js +14 -13
  40. package/lib/assess/propagators/path/join.js +5 -1
  41. package/lib/assess/propagators/path/normalize.js +1 -2
  42. package/lib/assess/propagators/path/parse.js +1 -1
  43. package/lib/assess/propagators/path/relative.js +7 -5
  44. package/lib/assess/propagators/path/resolve.js +11 -2
  45. package/lib/assess/propagators/querystring/escape.js +20 -18
  46. package/lib/assess/propagators/querystring/parse.js +7 -5
  47. package/lib/assess/propagators/querystring/stringify.js +25 -24
  48. package/lib/assess/propagators/querystring/unescape.js +20 -18
  49. package/lib/assess/propagators/sequelize/sql-string-escape.js +1 -1
  50. package/lib/assess/propagators/sequelize/sql-string-format-named-parameters.js +1 -1
  51. package/lib/assess/propagators/sequelize/sql-string-format.js +3 -3
  52. package/lib/assess/propagators/sequelize/utils.js +2 -2
  53. package/lib/assess/propagators/string-prototype-replace.js +30 -28
  54. package/lib/assess/propagators/string-prototype-split.js +36 -36
  55. package/lib/assess/propagators/string-prototype-trim.js +15 -17
  56. package/lib/assess/propagators/string.js +12 -16
  57. package/lib/assess/propagators/template-escape.js +87 -0
  58. package/lib/assess/propagators/templates.js +10 -11
  59. package/lib/assess/propagators/url/url-prototype-parse.js +5 -6
  60. package/lib/assess/propagators/url/url-url.js +51 -43
  61. package/lib/assess/propagators/util/format.js +1 -1
  62. package/lib/assess/propagators/v8/init-hooks.js +3 -3
  63. package/lib/assess/propagators/validator/init-hooks.js +22 -22
  64. package/lib/assess/sinks/common.js +10 -5
  65. package/lib/assess/sinks/dustjs-linkedin-xss.js +131 -0
  66. package/lib/assess/sinks/libxmljs-xxe.js +1 -1
  67. package/lib/assess/sinks/mongodb.js +2 -1
  68. package/lib/assess/sinks/ssrf-url.js +1 -1
  69. package/lib/constants.js +4 -1
  70. package/lib/core/arch-components/dynamodb.js +1 -2
  71. package/lib/core/arch-components/dynamodbv3.js +44 -0
  72. package/lib/core/arch-components/index.js +1 -0
  73. package/lib/core/arch-components/rethinkdb.js +53 -0
  74. package/lib/core/config/options.js +3 -2
  75. package/lib/core/rewrite/injections.js +8 -0
  76. package/lib/core/stacktrace.js +2 -1
  77. package/lib/feature-set.js +1 -1
  78. package/lib/hooks/frameworks/base.js +8 -2
  79. package/lib/hooks/frameworks/http.js +23 -16
  80. package/lib/hooks/frameworks/http2.js +73 -0
  81. package/lib/hooks/frameworks/index.js +8 -3
  82. package/lib/hooks/http.js +112 -128
  83. package/lib/hooks/object-to-primitive.js +6 -7
  84. package/lib/hooks/patcher.js +75 -44
  85. package/lib/hooks/require.js +16 -22
  86. package/lib/instrumentation.js +0 -3
  87. package/lib/protect/rules/nosqli/nosql-injection-rule.js +228 -0
  88. package/lib/protect/rules/rule-factory.js +2 -2
  89. package/lib/protect/service.js +23 -11
  90. package/lib/protect/sinks/mongodb.js +56 -55
  91. package/lib/reporter/translations/to-protobuf/dtm/index.js +1 -1
  92. package/lib/reporter/translations/to-protobuf/dtm/ip-denylist-details.js +1 -1
  93. package/lib/reporter/translations/to-protobuf/dtm/rasp-rule-sample.js +1 -1
  94. package/lib/reporter/translations/to-protobuf/settings/defend-features.js +8 -6
  95. package/lib/reporter/translations/to-protobuf/settings/exclusions.js +5 -4
  96. package/lib/tracker.js +13 -65
  97. package/lib/util/some.js +27 -0
  98. package/lib/util/source-map.js +1 -1
  99. package/package.json +15 -16
  100. package/lib/hooks/frameworks/https.js +0 -42
  101. package/lib/protect/rules/nosqli/no-sql-injection-rule.js +0 -109
  102. package/node_modules/bindings/LICENSE.md +0 -22
  103. package/node_modules/bindings/README.md +0 -98
  104. package/node_modules/bindings/bindings.js +0 -221
  105. package/node_modules/bindings/package.json +0 -32
  106. package/node_modules/file-uri-to-path/.npmignore +0 -1
  107. package/node_modules/file-uri-to-path/.travis.yml +0 -30
  108. package/node_modules/file-uri-to-path/History.md +0 -21
  109. package/node_modules/file-uri-to-path/LICENSE +0 -20
  110. package/node_modules/file-uri-to-path/README.md +0 -74
  111. package/node_modules/file-uri-to-path/index.d.ts +0 -2
  112. package/node_modules/file-uri-to-path/index.js +0 -66
  113. package/node_modules/file-uri-to-path/package.json +0 -36
  114. package/node_modules/file-uri-to-path/test/test.js +0 -24
  115. package/node_modules/file-uri-to-path/test/tests.json +0 -13
  116. package/node_modules/glossy/LICENSE +0 -19
  117. package/node_modules/glossy/README.md +0 -129
  118. package/node_modules/glossy/index.js +0 -12
  119. package/node_modules/glossy/lib/glossy/parse.js +0 -520
  120. package/node_modules/glossy/lib/glossy/produce.js +0 -459
  121. package/node_modules/glossy/package.json +0 -47
  122. package/node_modules/glossy/test/decide.js +0 -7
  123. package/node_modules/glossy/test/decode_pri.js +0 -24
  124. package/node_modules/glossy/test/parse_3164.js +0 -104
  125. package/node_modules/glossy/test/parse_5424.js +0 -106
  126. package/node_modules/glossy/test/parse_5848.js +0 -40
  127. package/node_modules/glossy/test/parse_8601.js +0 -14
  128. package/node_modules/glossy/test/parse_rfc3339.js +0 -9
  129. package/node_modules/glossy/test/produce.js +0 -162
  130. package/node_modules/glossy/test/runner.js +0 -40
  131. package/node_modules/glossy/test/structure_data.js +0 -24
  132. package/node_modules/nan/CHANGELOG.md +0 -537
  133. package/node_modules/nan/LICENSE.md +0 -13
  134. package/node_modules/nan/README.md +0 -455
  135. package/node_modules/nan/doc/asyncworker.md +0 -146
  136. package/node_modules/nan/doc/buffers.md +0 -54
  137. package/node_modules/nan/doc/callback.md +0 -76
  138. package/node_modules/nan/doc/converters.md +0 -41
  139. package/node_modules/nan/doc/errors.md +0 -226
  140. package/node_modules/nan/doc/json.md +0 -62
  141. package/node_modules/nan/doc/maybe_types.md +0 -583
  142. package/node_modules/nan/doc/methods.md +0 -664
  143. package/node_modules/nan/doc/new.md +0 -147
  144. package/node_modules/nan/doc/node_misc.md +0 -123
  145. package/node_modules/nan/doc/object_wrappers.md +0 -263
  146. package/node_modules/nan/doc/persistent.md +0 -296
  147. package/node_modules/nan/doc/scopes.md +0 -73
  148. package/node_modules/nan/doc/script.md +0 -38
  149. package/node_modules/nan/doc/string_bytes.md +0 -62
  150. package/node_modules/nan/doc/v8_internals.md +0 -199
  151. package/node_modules/nan/doc/v8_misc.md +0 -85
  152. package/node_modules/nan/include_dirs.js +0 -1
  153. package/node_modules/nan/nan.h +0 -2898
  154. package/node_modules/nan/nan_callbacks.h +0 -88
  155. package/node_modules/nan/nan_callbacks_12_inl.h +0 -514
  156. package/node_modules/nan/nan_callbacks_pre_12_inl.h +0 -520
  157. package/node_modules/nan/nan_converters.h +0 -72
  158. package/node_modules/nan/nan_converters_43_inl.h +0 -68
  159. package/node_modules/nan/nan_converters_pre_43_inl.h +0 -42
  160. package/node_modules/nan/nan_define_own_property_helper.h +0 -29
  161. package/node_modules/nan/nan_implementation_12_inl.h +0 -430
  162. package/node_modules/nan/nan_implementation_pre_12_inl.h +0 -263
  163. package/node_modules/nan/nan_json.h +0 -166
  164. package/node_modules/nan/nan_maybe_43_inl.h +0 -356
  165. package/node_modules/nan/nan_maybe_pre_43_inl.h +0 -268
  166. package/node_modules/nan/nan_new.h +0 -340
  167. package/node_modules/nan/nan_object_wrap.h +0 -156
  168. package/node_modules/nan/nan_persistent_12_inl.h +0 -132
  169. package/node_modules/nan/nan_persistent_pre_12_inl.h +0 -242
  170. package/node_modules/nan/nan_private.h +0 -73
  171. package/node_modules/nan/nan_string_bytes.h +0 -305
  172. package/node_modules/nan/nan_typedarray_contents.h +0 -96
  173. package/node_modules/nan/nan_weak.h +0 -437
  174. package/node_modules/nan/package.json +0 -41
  175. package/node_modules/nan/tools/1to2.js +0 -412
  176. package/node_modules/nan/tools/README.md +0 -14
  177. package/node_modules/nan/tools/package.json +0 -19
  178. package/node_modules/unix-dgram/LICENSE +0 -13
  179. package/node_modules/unix-dgram/README.md +0 -107
  180. package/node_modules/unix-dgram/binding.gyp +0 -20
  181. package/node_modules/unix-dgram/build/Makefile +0 -324
  182. package/node_modules/unix-dgram/build/Release/.deps/Release/obj.target/unix_dgram/src/unix_dgram.o.d +0 -58
  183. package/node_modules/unix-dgram/build/Release/.deps/Release/obj.target/unix_dgram.node.d +0 -1
  184. package/node_modules/unix-dgram/build/Release/.deps/Release/unix_dgram.node.d +0 -1
  185. package/node_modules/unix-dgram/build/Release/obj.target/unix_dgram/src/unix_dgram.o +0 -0
  186. package/node_modules/unix-dgram/build/Release/obj.target/unix_dgram.node +0 -0
  187. package/node_modules/unix-dgram/build/Release/unix_dgram.node +0 -0
  188. package/node_modules/unix-dgram/build/binding.Makefile +0 -6
  189. package/node_modules/unix-dgram/build/config.gypi +0 -213
  190. package/node_modules/unix-dgram/build/unix_dgram.target.mk +0 -159
  191. package/node_modules/unix-dgram/lib/unix_dgram.js +0 -168
  192. package/node_modules/unix-dgram/package.json +0 -36
  193. package/node_modules/unix-dgram/src/unix_dgram.cc +0 -404
  194. package/node_modules/unix-dgram/src/win_dummy.cc +0 -7
  195. package/node_modules/unix-dgram/test/test-connect-callback.js +0 -68
  196. package/node_modules/unix-dgram/test/test-connect.js +0 -53
  197. package/node_modules/unix-dgram/test/test-dgram-unix.js +0 -58
  198. package/node_modules/unix-dgram/test/test-send-error.js +0 -26
  199. package/node_modules/winston-syslog/.eslintrc +0 -7
  200. package/node_modules/winston-syslog/.travis.yml +0 -14
  201. package/node_modules/winston-syslog/CHANGELOG.md +0 -9
  202. package/node_modules/winston-syslog/LICENSE +0 -20
  203. package/node_modules/winston-syslog/README.md +0 -135
  204. package/node_modules/winston-syslog/lib/utils.js +0 -26
  205. package/node_modules/winston-syslog/lib/winston-syslog.js +0 -385
  206. package/node_modules/winston-syslog/package.json +0 -56
  207. package/node_modules/winston-syslog/test/format-test.js +0 -122
  208. package/node_modules/winston-syslog/test/syslog-test.js +0 -95
  209. package/node_modules/winston-syslog/test/unix-connect-test.js +0 -133
@@ -19,7 +19,6 @@ const TagRange = require('../../models/tag-range');
19
19
  const tagRangeUtil = require('../../models/tag-range/util');
20
20
  const tracker = require('../../../tracker');
21
21
  const path = require('path');
22
- let trackingSeparators;
23
22
 
24
23
  /**
25
24
  * Splits string by separator
@@ -31,8 +30,9 @@ let trackingSeparators;
31
30
  */
32
31
  function splitString(str, win32) {
33
32
  // windows treats both (forward and backward) slashes as separators
34
- const posixRegEx = trackingSeparators ? /(?=\/)/g : /(\/)/g;
35
- const win32RegEx = trackingSeparators ? /(?=[/\\])/g : /[/\\]/g;
33
+ const posixRegEx = /(?=\/)/g;
34
+ const win32RegEx = /(?=[/\\])/g;
35
+
36
36
  if (win32) {
37
37
  str = str.replace(/\//g, '\\').split(win32RegEx);
38
38
  } else {
@@ -55,29 +55,26 @@ function splitString(str, win32) {
55
55
  *
56
56
  * @param {Object} meta object of metadata from result/arg
57
57
  * @param {(segmentOffset: number) => boolean} meta.evaluator expression to determine the proper position of segment in string
58
- * @param {number} meta.offset offset of full arg from result of path.resolve
59
58
  * @param {string} meta.str result from path.resolve or arg
59
+ * @param {number} offset offset of full arg from result of path.resolve
60
60
  * @param {string} segment path segment from one of the args to path.resolve
61
61
  */
62
- function getSegmentOffset({ str, offset, evaluator }, segment, win32) {
62
+ function getSegmentOffset({ str, evaluator }, offset, segment, win32) {
63
63
  // as the segments in each arg and in the result get traversed,
64
64
  // winnow away the string to ensure we are finding the proper
65
65
  // segment within the path
66
66
  const substr = str.substring(offset);
67
67
  let segmentOffset = substr.indexOf(segment);
68
68
  // If tracking separators, evaluator will fail on extensions
69
- if (trackingSeparators && substr === `.${segment}`) {
69
+ if (substr === `.${segment}`) {
70
70
  return segmentOffset + offset;
71
71
  }
72
72
  // Adjust offset if the segment does not start with a separator
73
73
  const { sep } = path[win32 ? 'win32' : 'posix'];
74
- if (
75
- trackingSeparators &&
76
- substr.startsWith(sep) &&
77
- !segment.startsWith(sep)
78
- ) {
74
+ if (substr.startsWith(sep) && !segment.startsWith(sep)) {
79
75
  segmentOffset--;
80
76
  }
77
+
81
78
  return evaluator(segmentOffset) ? segmentOffset + offset : -1;
82
79
  }
83
80
 
@@ -90,7 +87,12 @@ function getSegmentOffset({ str, offset, evaluator }, segment, win32) {
90
87
  */
91
88
  function isWithinTag(str, start, tag) {
92
89
  const stop = str.length - 1 + start;
93
- return tag.overlaps({ start, stop, tag: tag.tag });
90
+
91
+ return (
92
+ (stop <= tag.stop && stop >= tag.start) ||
93
+ (start >= tag.start && start <= tag.stop) ||
94
+ (tag.start >= start && tag.start <= stop)
95
+ );
94
96
  }
95
97
 
96
98
  /**
@@ -103,6 +105,7 @@ function isWithinTag(str, start, tag) {
103
105
  */
104
106
  function adjustStart({ tag, argOffset, offset }) {
105
107
  const start = tag.start - argOffset;
108
+
106
109
  return start > 0 ? start + offset : offset;
107
110
  }
108
111
 
@@ -154,16 +157,13 @@ function maybeUpdateResultMeta({ index, arg, resultMeta }) {
154
157
  }
155
158
 
156
159
  /**
157
- * Encapsulates moving the resultOffset based on a segment
160
+ * Calculates a new offset based on a segment
158
161
  *
159
- * @param {Object} resultMeta metadata from result of path.resolve
160
- * @param {Object} argMeta metadata for a given argument
162
+ * @param {Object} offset offset of the object
161
163
  * @param {string} segment path segment from one of the args to path.resolve
162
164
  */
163
- function calculateNewOffset(resultMeta, argMeta, segment) {
164
- const separatorOffset = trackingSeparators ? 0 : 1;
165
- resultMeta.offset = resultMeta.offset + segment.length + separatorOffset;
166
- argMeta.offset = argMeta.offset + segment.length + separatorOffset;
165
+ function calculateNewOffset(offset, segment) {
166
+ return offset + segment.length;
167
167
  }
168
168
 
169
169
  /**
@@ -173,10 +173,89 @@ function calculateNewOffset(resultMeta, argMeta, segment) {
173
173
  * @param {string} segment path segment to check
174
174
  * @return {boolean}
175
175
  */
176
- function applicableSegment(segment) {
176
+ function isApplicableSegment(segment) {
177
177
  return segment !== '.' && segment !== '..' && segment !== '';
178
178
  }
179
179
 
180
+ /**
181
+ * Filters invalid segments like those that are not part of the end result.
182
+ * It also calculates additional offset.
183
+ *
184
+ * @param {*} segments splitted path into segments
185
+ * @param {Object} resultMeta metadata from result of path.resolve
186
+ * @param {Object} data the data object of the propagate function
187
+ * @param {number} index the iteration index
188
+ * @param {boolean} win32 indicating win32 to replace `/` with `\'
189
+ */
190
+ function filterSegmentsAndCalculateOffset(
191
+ segments,
192
+ resultMeta,
193
+ data,
194
+ index,
195
+ win32
196
+ ) {
197
+ const { sep } = path[win32 ? 'win32' : 'posix'];
198
+ const isFirstIteration = index === 0;
199
+ const validSegments = [];
200
+ let additionalOffset = 0;
201
+
202
+ segments.reduce(
203
+ // eslint-disable-next-line complexity
204
+ (accumulator, segment) => {
205
+ let hasChange = false;
206
+ if (!isApplicableSegment(segment)) return accumulator;
207
+
208
+ if (!accumulator.isModified && !isFirstIteration) {
209
+ const previousArg = data.args[index - 1];
210
+
211
+ const sepAdded = !segment.startsWith(sep) && !previousArg.endsWith(sep);
212
+ const sepTaken = segment.startsWith(sep) && previousArg.endsWith(sep);
213
+ accumulator.isModified = sepAdded || sepTaken;
214
+ hasChange = sepAdded || sepTaken;
215
+ additionalOffset = hasChange ? (sepAdded ? 1 : -1) : 0;
216
+ }
217
+
218
+ const offset = getSegmentOffset(
219
+ resultMeta,
220
+ accumulator.offset + additionalOffset + accumulator.fileDotSeparator,
221
+ segment,
222
+ win32
223
+ );
224
+
225
+ // no reason to proceed if segment is not in final result
226
+ if (offset === -1) {
227
+ if (hasChange) {
228
+ additionalOffset = 0;
229
+ accumulator.isModified = false;
230
+ }
231
+
232
+ return accumulator;
233
+ }
234
+
235
+ // in case we have a file we need to increment the offset
236
+ if (resultMeta.str[offset + segment.length] === '.') {
237
+ accumulator.fileDotSeparator = 1;
238
+ }
239
+
240
+ validSegments.push(segment);
241
+ accumulator.offset = calculateNewOffset(accumulator.offset, segment);
242
+ accumulator.isModified = true;
243
+
244
+ return accumulator;
245
+ },
246
+ {
247
+ offset: resultMeta.offset,
248
+ fileDotSeparator: 0,
249
+ isModified: false
250
+ }
251
+ );
252
+
253
+ return {
254
+ additionalOffset,
255
+ segments: validSegments
256
+ };
257
+ }
258
+
180
259
  /**
181
260
  * Moves the tag ranges properly based on if a path segment exists in the
182
261
  * result
@@ -184,43 +263,66 @@ function applicableSegment(segment) {
184
263
  * @param {Object} resultMeta metadata for the result
185
264
  * @param {Object} argMeta meta for a given argument
186
265
  * @param {boolean} win32 indicating win32 to replace `/` with `\'
266
+ * @param {Object} data the data object of the propagate function
267
+ * @param {number} index the iteration index
187
268
  */
188
- function adjustTagsToPart(resultMeta, argMeta, win32) {
269
+ function adjustTagsToPart(resultMeta, argMeta, win32, data, index) {
189
270
  const { str, tagRanges } = argMeta;
190
- const segments = splitString(str, win32);
191
- const newTags = [];
192
- segments.forEach((segment) => {
193
- if (!applicableSegment(segment)) {
194
- return;
195
- }
196
- const offset = getSegmentOffset(resultMeta, segment, win32);
197
- // no reason to proceed if segment is not in final result
198
- if (offset === -1) {
199
- return;
200
- }
271
+ const { segments, additionalOffset } = filterSegmentsAndCalculateOffset(
272
+ splitString(str, win32),
273
+ resultMeta,
274
+ data,
275
+ index,
276
+ win32
277
+ );
278
+
279
+ // updating the offset
280
+ resultMeta.offset += additionalOffset;
281
+
282
+ return segments.reduce((newTags, segment) => {
283
+ const offset = getSegmentOffset(
284
+ resultMeta,
285
+ resultMeta.offset,
286
+ segment,
287
+ win32
288
+ );
289
+
290
+ const argOffset = getSegmentOffset(argMeta, argMeta.offset, segment, win32);
201
291
 
202
- const argOffset = getSegmentOffset(argMeta, segment, win32);
292
+ // updating the offset
293
+ resultMeta.offset = calculateNewOffset(resultMeta.offset, segment);
294
+ argMeta.offset = calculateNewOffset(argMeta.offset, segment);
203
295
 
204
- calculateNewOffset(resultMeta, argMeta, segment);
296
+ // in case we have a file we need to increment the offset
297
+ if (resultMeta.str[offset + segment.length] === '.') {
298
+ resultMeta.offset += 1;
299
+ }
205
300
 
206
301
  tagRanges.forEach((tag) => {
207
- if (isWithinTag(segment, argOffset, tag)) {
208
- const start = adjustStart({ tag, argOffset, offset });
209
- const stop = adjustStop({ tag, argOffset, offset, segment });
302
+ if (!isWithinTag(segment, argOffset, tag)) return;
210
303
 
211
- newTags.push(new TagRange(start, stop, tag.tag));
212
- }
304
+ const start = adjustStart({
305
+ tag,
306
+ argOffset,
307
+ offset
308
+ });
309
+ const stop = adjustStop({
310
+ tag,
311
+ argOffset,
312
+ offset,
313
+ segment
314
+ });
315
+
316
+ newTags.push(new TagRange(start, stop, tag.tag));
213
317
  });
214
- });
215
318
 
216
- return newTags;
319
+ return newTags;
320
+ }, []);
217
321
  }
218
322
 
219
- function propagate({ resultMeta, data, win32, trackSeparators }) {
220
- trackingSeparators = trackSeparators;
323
+ function propagate({ resultMeta, data, win32 }) {
221
324
  if (!resultMeta.evaluator) {
222
- resultMeta.evaluator = (segmentOffset) =>
223
- segmentOffset === (trackingSeparators ? 0 : 1);
325
+ resultMeta.evaluator = (segmentOffset) => segmentOffset === 0;
224
326
  }
225
327
 
226
328
  data.args.forEach((arg, index) => {
@@ -231,16 +333,23 @@ function propagate({ resultMeta, data, win32, trackSeparators }) {
231
333
  evaluator: (segmentOffset) => segmentOffset > -1,
232
334
  offset: 0,
233
335
  str: arg,
234
- tagRanges: argData.tracked ? argData.tagRanges : []
336
+ tagRanges: argData ? argData.tagRanges : []
235
337
  };
236
338
 
237
- const targetTagRanges = adjustTagsToPart(resultMeta, argMeta, win32);
339
+ const targetTagRanges = adjustTagsToPart(
340
+ resultMeta,
341
+ argMeta,
342
+ win32,
343
+ data,
344
+ index
345
+ );
238
346
 
239
347
  if (targetTagRanges.length > 0) {
240
348
  resultMeta.parents.push(argData.event);
241
349
  tagRangeUtil.addAllInPlace(resultMeta.tagRanges, targetTagRanges);
242
350
  }
243
351
  });
352
+
244
353
  trackResult(resultMeta, data);
245
354
  }
246
355
 
@@ -42,7 +42,7 @@ module.exports.handle = function handle() {
42
42
  if (!data.args[0]) return;
43
43
 
44
44
  const trackingData = tracker.getData(data.args[0]);
45
- if (!trackingData.tracked) return;
45
+ if (!trackingData) return;
46
46
 
47
47
  // path.dirname() does a slice at 0 to the calculated end separator
48
48
  const tagRanges = createSubsetTagRanges({
@@ -57,19 +57,20 @@ module.exports.handle = function handle() {
57
57
 
58
58
  if (!tagRanges.length) return;
59
59
 
60
- const result = tracker.track(data.result);
61
- const resultData = tracker.getData(result);
60
+ const tracked = tracker.track(data.result);
62
61
  const parentEvent = trackingData.event;
63
- resultData.tagRanges = tagRanges;
64
- resultData.event = new PropagationEvent({
65
- context: new CallContext(data),
66
- parents: [parentEvent],
67
- signature,
68
- source: 'P',
69
- tagRanges,
70
- target: 'R'
71
- });
72
- data.result = result;
62
+ if (tracked) {
63
+ tracked.props.tagRanges = tagRanges;
64
+ tracked.props.event = new PropagationEvent({
65
+ context: new CallContext(data),
66
+ parents: [parentEvent],
67
+ signature,
68
+ source: 'P',
69
+ tagRanges,
70
+ target: 'R'
71
+ });
72
+ data.result = tracked.str;
73
+ }
73
74
  }
74
75
  });
75
76
  }
@@ -42,7 +42,7 @@ module.exports.handle = function handle() {
42
42
  if (!data.args[0] || !data.result) return;
43
43
 
44
44
  const trackingData = tracker.getData(data.args[0]);
45
- if (!trackingData.tracked) return;
45
+ if (!trackingData) return;
46
46
 
47
47
  // The path.extname() implementation does a substr on the argument
48
48
  // based on the calculated index of the last dot
@@ -62,19 +62,20 @@ module.exports.handle = function handle() {
62
62
  // no tags propagated to the result
63
63
  if (!tagRanges.length) return;
64
64
 
65
- const result = tracker.track(data.result);
66
- const resultData = tracker.getData(result);
65
+ const tracked = tracker.track(data.result);
67
66
  const parentEvent = trackingData.event;
68
- resultData.tagRanges = tagRanges;
69
- resultData.event = new PropagationEvent({
70
- context: new CallContext(data),
71
- parents: [parentEvent],
72
- signature,
73
- source: 'P',
74
- tagRanges,
75
- target: 'R'
76
- });
77
- data.result = result;
67
+ if (tracked) {
68
+ tracked.props.tagRanges = tagRanges;
69
+ tracked.props.event = new PropagationEvent({
70
+ context: new CallContext(data),
71
+ parents: [parentEvent],
72
+ signature,
73
+ source: 'P',
74
+ tagRanges,
75
+ target: 'R'
76
+ });
77
+ data.result = tracked.str;
78
+ }
78
79
  }
79
80
  });
80
81
  }
@@ -31,7 +31,11 @@ function hookPath(path) {
31
31
  resultMeta.offset = 0;
32
32
  resultMeta.evaluator = (segmentOffset) => segmentOffset === 0;
33
33
  }
34
- propagate({ data, resultMeta, win32: os === 'win32' });
34
+ propagate({
35
+ data,
36
+ resultMeta,
37
+ win32: os === 'win32'
38
+ });
35
39
  }
36
40
  });
37
41
  }
@@ -46,8 +46,7 @@ module.exports.handle = function handle() {
46
46
  propagate({
47
47
  resultMeta,
48
48
  data,
49
- win32: os === 'win32',
50
- trackSeparators: true
49
+ win32: os === 'win32'
51
50
  });
52
51
  }
53
52
  });
@@ -24,7 +24,7 @@ const propagate = function propagate(data) {
24
24
  const props = tracker.getData(data.args[0]);
25
25
  const { result } = data;
26
26
 
27
- if (props.tracked && result) {
27
+ if (props && result) {
28
28
  const membrane = new DeserializationMembrane(data, props);
29
29
  data.result = membrane.wrap(result);
30
30
  }
@@ -35,7 +35,7 @@ const provider = {
35
35
  const { args, result } = data;
36
36
  const trackData = tracker.getData(args[1]);
37
37
 
38
- if (!trackData.tracked) {
38
+ if (!trackData) {
39
39
  return;
40
40
  }
41
41
 
@@ -61,10 +61,12 @@ const provider = {
61
61
  },
62
62
  data
63
63
  );
64
- data.result = tracker.track(data.result);
65
- const resultTrackData = tracker.getData(data.result);
66
- resultTrackData.tagRanges = shiftedRanges;
67
- resultTrackData.event = event;
64
+ const tracked = tracker.track(data.result);
65
+ if (tracked) {
66
+ data.result = tracked.str;
67
+ tracked.props.tagRanges = shiftedRanges;
68
+ tracked.props.event = event;
69
+ }
68
70
  }
69
71
  },
70
72
  /**
@@ -34,7 +34,12 @@ module.exports.handle = function handle() {
34
34
  if (!data.args[0]) return;
35
35
  const resultMeta = getResultMeta(data, 'resolve');
36
36
  const isAbsolute = absolutePath(data.args[0]);
37
- resultMeta.offset = isAbsolute ? 0 : process.cwd().length;
37
+
38
+ /*
39
+ plus one in case isAbsolute is false since our working deretory ends without slash
40
+ example: /Users/John/Documents/Projects/node-agent
41
+ */
42
+ resultMeta.offset = isAbsolute ? 0 : process.cwd().length + 1;
38
43
 
39
44
  // a work-around for paths like C:\Windows
40
45
  if (
@@ -45,7 +50,11 @@ module.exports.handle = function handle() {
45
50
  resultMeta.evaluator = (segmentOffset) => segmentOffset > -1;
46
51
  }
47
52
 
48
- propagate({ data, resultMeta, win32: os === 'win32' });
53
+ propagate({
54
+ data,
55
+ resultMeta,
56
+ win32: os === 'win32'
57
+ });
49
58
  }
50
59
  });
51
60
  }
@@ -21,34 +21,36 @@ const qsUtils = require('./utils');
21
21
 
22
22
  function handler(data) {
23
23
  const input = data.args[0];
24
+ const trackedData = tracker.getData(input);
24
25
 
25
- if (!input || !tracker.getData(input).tracked) {
26
+ if (!input || !trackedData) {
26
27
  return;
27
28
  }
28
29
 
29
30
  // adjust tag ranges
30
31
  const tagRanges = [];
31
- tracker.getData(input).tagRanges.forEach((tag) => {
32
+ trackedData.tagRanges.forEach((tag) => {
32
33
  tagRanges.push(qsUtils.adjustRangeEscape(tag, 0, input));
33
34
  });
34
35
  tagRanges.push(new TagRange(0, data.result.length - 1, 'url-encoded'));
35
36
 
36
- const result = tracker.track(data.result);
37
- const trackData = tracker.getData(result);
38
- trackData.tagRanges = tagRanges;
39
- trackData.event = new PropagationEvent({
40
- context: new CallContext({
41
- ...data,
42
- obj: null
43
- }),
44
- parents: [trackData.event],
45
- signature: new Signature('querystring.escape'),
46
- source: 'P',
47
- target: 'R',
48
- tagRanges,
49
- tags: ['url-encoded']
50
- });
51
- data.result = result;
37
+ const tracked = tracker.track(data.result);
38
+ if (tracked) {
39
+ tracked.props.tagRanges = tagRanges;
40
+ tracked.props.event = new PropagationEvent({
41
+ context: new CallContext({
42
+ ...data,
43
+ obj: null
44
+ }),
45
+ parents: [tracked.props.event],
46
+ signature: new Signature('querystring.escape'),
47
+ source: 'P',
48
+ target: 'R',
49
+ tagRanges,
50
+ tags: ['url-encoded']
51
+ });
52
+ data.result = tracked.str;
53
+ }
52
54
  }
53
55
 
54
56
  module.exports.handle = handler;
@@ -47,9 +47,11 @@ function getUnescapeWrapper(data, unescape) {
47
47
 
48
48
  // track the part w/ trimmed ranges if applicable
49
49
  if (tagRanges.length) {
50
- result = tracker.track(part);
51
- resultData = tracker.getData(result);
52
- resultData.tagRanges = tagRanges;
50
+ const tracked = tracker.track(part);
51
+ if (tracked) {
52
+ result = tracked.str;
53
+ tracked.props.tagRanges = tagRanges;
54
+ }
53
55
  } else {
54
56
  result = part;
55
57
  }
@@ -58,7 +60,7 @@ function getUnescapeWrapper(data, unescape) {
58
60
  result = Scopes.runInAllowAllScope(() => unescape(result));
59
61
  resultData = tracker.getData(result);
60
62
 
61
- if (resultData.tracked) {
63
+ if (resultData) {
62
64
  resultData.event = new PropagationEvent({
63
65
  context: new CallContext({
64
66
  ...data,
@@ -91,7 +93,7 @@ function pre(data) {
91
93
  }
92
94
  const trackingData = tracker.getData(input);
93
95
 
94
- if (!trackingData.tracked) {
96
+ if (!trackingData) {
95
97
  return;
96
98
  }
97
99
 
@@ -129,7 +129,7 @@ class OnEscapeHandler {
129
129
  // set current key for reference if when array-valued
130
130
  this.currentKey = {
131
131
  value: escaped,
132
- tagRanges: trackingData.tracked ? trackingData.tagRanges : null
132
+ tagRanges: trackingData ? trackingData.tagRanges : null
133
133
  };
134
134
 
135
135
  // capture track info before updating state
@@ -175,7 +175,7 @@ class OnEscapeHandler {
175
175
  this.offset += this.currentKey.value.length + this.eqLen;
176
176
  }
177
177
 
178
- if (trackingData.tracked) {
178
+ if (trackingData) {
179
179
  ret.push({
180
180
  offset: this.offset,
181
181
  tagRanges: trackingData.tagRanges,
@@ -279,34 +279,35 @@ function post(data) {
279
279
  }
280
280
 
281
281
  const tracked = tracker.track(data.result);
282
- const trackData = tracker.getData(tracked);
283
282
 
284
283
  if (data.state.escape === querystring.escape) {
285
284
  data.state.tagRanges.push(
286
285
  new TagRange(0, data.result.length - 1, 'url-encoded')
287
286
  );
288
287
  }
289
- const sorted = _.sortBy(data.state.tagRanges, 'start');
290
- trackData.tagRanges = [];
291
- tagRangeUtil.addAllInPlace(trackData.tagRanges, sorted);
292
-
293
- // stringify / encode
294
- const method = data.funcKey.split('.')[1];
295
-
296
- trackData.event = new PropagationEvent({
297
- context: new CallContext({
298
- ...data,
299
- args: data.state.origArgs,
300
- obj: null
301
- }),
302
- parents: Array.from(data.state.events),
303
- signature: new Signature(`querystring.${method}`),
304
- source: 'P',
305
- tagRanges: trackData.tagRanges,
306
- target: 'R',
307
- tags: ['url-encoded']
308
- });
309
- data.result = tracked;
288
+ if (tracked) {
289
+ const sorted = _.sortBy(data.state.tagRanges, 'start');
290
+ tracked.props.tagRanges = [];
291
+ tagRangeUtil.addAllInPlace(tracked.props.tagRanges, sorted);
292
+
293
+ // stringify / encode
294
+ const method = data.funcKey.split('.')[1];
295
+
296
+ tracked.props.event = new PropagationEvent({
297
+ context: new CallContext({
298
+ ...data,
299
+ args: data.state.origArgs,
300
+ obj: null
301
+ }),
302
+ parents: Array.from(data.state.events),
303
+ signature: new Signature(`querystring.${method}`),
304
+ source: 'P',
305
+ tagRanges: tracked.props.tagRanges,
306
+ target: 'R',
307
+ tags: ['url-encoded']
308
+ });
309
+ data.result = tracked.str;
310
+ }
310
311
  }
311
312
 
312
313
  module.exports.handle = { pre, post };