data-structure-typed 2.2.1 → 2.2.3

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 (83) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/README.md +440 -1190
  3. package/README_CN.md +509 -0
  4. package/SECURITY.md +962 -11
  5. package/SECURITY.zh-CN.md +966 -0
  6. package/SPECIFICATION.md +689 -30
  7. package/SPECIFICATION.zh-CN.md +715 -0
  8. package/SPONSOR.zh-CN.md +62 -0
  9. package/SPONSOR_POLISHED.md +62 -0
  10. package/benchmark/report.html +1 -1
  11. package/benchmark/report.json +215 -172
  12. package/dist/cjs/index.cjs +163 -0
  13. package/dist/cjs/index.cjs.map +1 -1
  14. package/dist/cjs-legacy/index.cjs +164 -0
  15. package/dist/cjs-legacy/index.cjs.map +1 -1
  16. package/dist/esm/index.mjs +163 -0
  17. package/dist/esm/index.mjs.map +1 -1
  18. package/dist/esm-legacy/index.mjs +164 -0
  19. package/dist/esm-legacy/index.mjs.map +1 -1
  20. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +96 -2
  21. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +103 -7
  22. package/dist/types/data-structures/binary-tree/bst.d.ts +156 -13
  23. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +84 -35
  24. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
  25. package/dist/types/data-structures/graph/directed-graph.d.ts +126 -1
  26. package/dist/types/data-structures/graph/undirected-graph.d.ts +160 -1
  27. package/dist/types/data-structures/hash/hash-map.d.ts +110 -27
  28. package/dist/types/data-structures/heap/heap.d.ts +107 -58
  29. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +72 -404
  30. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +121 -5
  31. package/dist/types/data-structures/queue/deque.d.ts +95 -67
  32. package/dist/types/data-structures/queue/queue.d.ts +90 -34
  33. package/dist/types/data-structures/stack/stack.d.ts +58 -40
  34. package/dist/types/data-structures/trie/trie.d.ts +109 -47
  35. package/dist/types/interfaces/binary-tree.d.ts +1 -0
  36. package/dist/umd/data-structure-typed.js +164 -0
  37. package/dist/umd/data-structure-typed.js.map +1 -1
  38. package/dist/umd/data-structure-typed.min.js +3 -3
  39. package/dist/umd/data-structure-typed.min.js.map +1 -1
  40. package/package.json +3 -2
  41. package/src/data-structures/binary-tree/avl-tree.ts +96 -2
  42. package/src/data-structures/binary-tree/binary-tree.ts +117 -7
  43. package/src/data-structures/binary-tree/bst.ts +322 -13
  44. package/src/data-structures/binary-tree/red-black-tree.ts +84 -35
  45. package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
  46. package/src/data-structures/graph/directed-graph.ts +126 -1
  47. package/src/data-structures/graph/undirected-graph.ts +160 -1
  48. package/src/data-structures/hash/hash-map.ts +110 -27
  49. package/src/data-structures/heap/heap.ts +107 -58
  50. package/src/data-structures/linked-list/doubly-linked-list.ts +72 -404
  51. package/src/data-structures/linked-list/singly-linked-list.ts +121 -5
  52. package/src/data-structures/queue/deque.ts +95 -67
  53. package/src/data-structures/queue/queue.ts +90 -34
  54. package/src/data-structures/stack/stack.ts +58 -40
  55. package/src/data-structures/trie/trie.ts +109 -47
  56. package/src/interfaces/binary-tree.ts +2 -0
  57. package/test/performance/benchmark-runner.ts +14 -11
  58. package/test/performance/data-structures/binary-tree/avl-tree.test.ts +8 -8
  59. package/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts +8 -8
  60. package/test/performance/data-structures/binary-tree/binary-tree.test.ts +6 -6
  61. package/test/performance/data-structures/binary-tree/bst.test.ts +5 -5
  62. package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +10 -10
  63. package/test/performance/reportor.ts +2 -1
  64. package/test/performance/single-suite-runner.ts +7 -4
  65. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +117 -0
  66. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +166 -0
  67. package/test/unit/data-structures/binary-tree/bst.test.ts +766 -8
  68. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +89 -37
  69. package/test/unit/data-structures/graph/directed-graph.test.ts +133 -0
  70. package/test/unit/data-structures/graph/undirected-graph.test.ts +167 -0
  71. package/test/unit/data-structures/hash/hash-map.test.ts +149 -3
  72. package/test/unit/data-structures/heap/heap.test.ts +182 -47
  73. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +118 -14
  74. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +121 -0
  75. package/test/unit/data-structures/queue/deque.test.ts +98 -67
  76. package/test/unit/data-structures/queue/queue.test.ts +85 -51
  77. package/test/unit/data-structures/stack/stack.test.ts +142 -33
  78. package/test/unit/data-structures/trie/trie.test.ts +135 -39
  79. package/tsup.leetcode.config.js +99 -0
  80. package/typedoc.json +2 -1
  81. package/POSTS_zh-CN.md +0 -54
  82. package/README_zh-CN.md +0 -1208
  83. package/SPECIFICATION_zh-CN.md +0 -81
package/SECURITY.md CHANGED
@@ -1,15 +1,966 @@
1
- # Security Policy
1
+ # SECURITY: data-structure-typed Security Guide
2
2
 
3
- ## Supported Versions
3
+ **Version:** 2.0.4
4
+ **Last Updated:** January 2026
5
+ **Status:** ✅ Actively Maintained
4
6
 
5
- | Version | Supported |
6
- |---------|--------------------|
7
- | 1.30.x | :white_check_mark: |
8
- | < 3.0 | :x: |
7
+ ---
9
8
 
10
- ## Reporting a Vulnerability
9
+ ## Table of Contents
11
10
 
12
- Create an [issue](https://github.com/zrwusa/data-structure-typed/issues/new/choose)
13
- and add the label "security" to report a vulnerability. Since this is right now maintained in free time,
14
- it might take a while. Providing a detailed description or a pull request with the fix are
15
- the best ways to support and speed up the process.
11
+ 1. [Security Overview](#security-overview)
12
+ 2. [Threat Model](#threat-model)
13
+ 3. [Security Guarantees](#security-guarantees)
14
+ 4. [Input Validation](#input-validation)
15
+ 5. [Comparator Safety](#comparator-safety)
16
+ 6. [Memory Management](#memory-management)
17
+ 7. [Type Safety](#type-safety)
18
+ 8. [Iteration Safety](#iteration-safety)
19
+ 9. [Denial of Service (DoS) Protection](#denial-of-service-dos-protection)
20
+ 10. [Dependency Security](#dependency-security)
21
+ 11. [Secure Usage Patterns](#secure-usage-patterns)
22
+ 12. [Known Limitations](#known-limitations)
23
+ 13. [Security Update Policy](#security-update-policy)
24
+ 14. [Reporting Security Issues](#reporting-security-issues)
25
+
26
+ ---
27
+
28
+ ## Security Overview
29
+
30
+ **data-structure-typed** is a data structure library focused on performance and usability. Security considerations are primarily around **resource exhaustion**, **type safety**, and **safe iteration**.
31
+
32
+ ### Scope
33
+
34
+ **This library is NOT designed to:**
35
+ - ❌ Encrypt or hash data
36
+ - ❌ Validate untrusted input
37
+ - ❌ Prevent timing attacks
38
+ - ❌ Protect against side-channel attacks
39
+ - ❌ Sanitize user input
40
+
41
+ **This library DOES protect against:**
42
+ - ✅ Buffer overflows (impossible in JavaScript)
43
+ - ✅ Type confusion attacks (TypeScript prevents at compile time)
44
+ - ✅ Null/undefined dereferences (defensive checks)
45
+ - ✅ Uncontrolled memory growth (clear APIs)
46
+ - ✅ Unsafe iteration patterns (documented behavior)
47
+
48
+ ### Design Philosophy
49
+
50
+ Library follows **fail-fast** principle:
51
+ - **Loud**: Errors that indicate bugs throw exceptions
52
+ - **Silent**: Missing keys return undefined (standard behavior)
53
+ - **Safe**: Type system prevents category errors at compile time
54
+
55
+ ---
56
+
57
+ ## Threat Model
58
+
59
+ ### Attack Vectors (In Scope)
60
+
61
+ #### 1. Unintended Memory Growth
62
+
63
+ **Risk:** Attacker adds millions of items, causing OOM
64
+
65
+ ```typescript
66
+ const tree = new RedBlackTree();
67
+ for (let i = 0; i < 1000000000; i++) {
68
+ tree.set(i, 'data'); // Unbounded growth
69
+ }
70
+ // Process runs out of memory
71
+ ```
72
+
73
+ **Mitigation:**
74
+ - Monitor `structure.size` property
75
+ - Implement size limits in application logic
76
+ - Clear structures when done: `structure.clear()`
77
+
78
+ ```typescript
79
+ // ✅ Safe pattern
80
+ const tree = new RedBlackTree();
81
+ const MAX_SIZE = 100000;
82
+
83
+ function addSafe(key, value) {
84
+ if (tree.size >= MAX_SIZE) {
85
+ throw new Error('Structure at capacity');
86
+ }
87
+ tree.set(key, value);
88
+ }
89
+ ```
90
+
91
+ #### 2. Comparator Exceptions
92
+
93
+ **Risk:** Malicious comparator throws or crashes
94
+
95
+ ```typescript
96
+ const tree = new RedBlackTree<number>(
97
+ (a, b) => {
98
+ if (a === null) throw new Error('Hacked!');
99
+ return a - b;
100
+ }
101
+ );
102
+
103
+ tree.set(null, 'value'); // Throws unhandled exception
104
+ ```
105
+
106
+ **Mitigation:**
107
+ - Always wrap comparators in try-catch if untrusted
108
+ - Use pure functions (no side effects)
109
+ - Validate inputs before tree operations
110
+
111
+ ```typescript
112
+ // ✅ Safe pattern
113
+ function safeComparator(a, b) {
114
+ try {
115
+ if (!isNumber(a) || !isNumber(b)) {
116
+ throw new TypeError('Expected numbers');
117
+ }
118
+ return a - b;
119
+ } catch (error) {
120
+ logger.error('Comparator failed:', error);
121
+ throw error; // Explicit error handling
122
+ }
123
+ }
124
+
125
+ const tree = new RedBlackTree<number>(safeComparator);
126
+ ```
127
+
128
+ #### 3. Iterator Mutation
129
+
130
+ **Risk:** Mutating structure during iteration causes inconsistent state
131
+
132
+ ```typescript
133
+ const tree = new RedBlackTree([1, 2, 3]);
134
+
135
+ for (const item of tree) {
136
+ tree.delete(item); // Modifying while iterating
137
+ // Behavior is undefined
138
+ }
139
+ ```
140
+
141
+ **Mitigation:**
142
+ - Don't mutate during iteration
143
+ - Collect mutations and apply after
144
+ - Use snapshot iteration if needed
145
+
146
+ ```typescript
147
+ // ✅ Safe pattern
148
+ const tree = new RedBlackTree([1, 2, 3]);
149
+
150
+ // Method 1: Collect mutations
151
+ const toDelete = [];
152
+ for (const item of tree) {
153
+ if (shouldDelete(item)) toDelete.push(item);
154
+ }
155
+ toDelete.forEach(item => tree.delete(item));
156
+
157
+ // Method 2: Snapshot iteration
158
+ const items = [...tree]; // Create snapshot
159
+ items.forEach(item => tree.delete(item));
160
+ ```
161
+
162
+ #### 4. Type Confusion
163
+
164
+ **Risk:** Passing wrong types bypasses type system at runtime
165
+
166
+ ```typescript
167
+ const tree = new RedBlackTree<number>();
168
+
169
+ // At runtime, TypeScript types are erased
170
+ tree.set('not-a-number' as any, 'value');
171
+ // Type system didn't prevent this
172
+ ```
173
+
174
+ **Mitigation:**
175
+ - Use strict TypeScript settings: `strict: true`
176
+ - Avoid `as any` assertions in untrusted code
177
+ - Validate types at runtime boundaries
178
+
179
+ ```typescript
180
+ // ✅ Safe pattern
181
+ interface ValidInput {
182
+ id: number;
183
+ name: string;
184
+ }
185
+
186
+ function addFromUntrustedSource(input: unknown) {
187
+ if (!isValidInput(input)) {
188
+ throw new TypeError('Invalid input');
189
+ }
190
+
191
+ const tree = new RedBlackTree<number, ValidInput>();
192
+ tree.set(input.id, input); // Now type-safe
193
+ }
194
+
195
+ function isValidInput(input: unknown): input is ValidInput {
196
+ return (
197
+ typeof input === 'object' &&
198
+ input !== null &&
199
+ typeof (input as any).id === 'number' &&
200
+ typeof (input as any).name === 'string'
201
+ );
202
+ }
203
+ ```
204
+
205
+ #### 5. Infinite Loops
206
+
207
+ **Risk:** Comparator causes infinite loop during tree operations
208
+
209
+ ```typescript
210
+ const tree = new RedBlackTree<number>(
211
+ (a, b) => {
212
+ // Intentionally broken comparator
213
+ return 0; // Always equal
214
+ }
215
+ );
216
+
217
+ tree.addMany([1, 2, 3, 4, 5]);
218
+ // May cause infinite loops or stack overflow
219
+ ```
220
+
221
+ **Mitigation:**
222
+ - Use strict comparators: consistent and deterministic
223
+ - Test comparators with large datasets
224
+ - Set timeout limits for tree operations
225
+
226
+ ```typescript
227
+ // ✅ Safe pattern
228
+ function strictComparator<T>(a: T, b: T): number {
229
+ if (a < b) return -1;
230
+ if (a > b) return 1;
231
+ return 0; // Only returns -1, 0, or 1
232
+ }
233
+
234
+ const tree = new RedBlackTree<number>(strictComparator);
235
+
236
+ // With timeout wrapper (application level)
237
+ function withTimeout<T>(fn: () => T, ms: number): T {
238
+ const controller = new AbortController();
239
+ const timeout = setTimeout(() => controller.abort(), ms);
240
+
241
+ try {
242
+ return fn();
243
+ } finally {
244
+ clearTimeout(timeout);
245
+ }
246
+ }
247
+
248
+ withTimeout(() => tree.addMany(items), 1000);
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Security Guarantees
254
+
255
+ ### What This Library Guarantees
256
+
257
+ | Guarantee | Status | Details |
258
+ |-----------|--------|---------|
259
+ | **No arbitrary code execution** | ✅ 100% | Only runs provided comparators |
260
+ | **No data leaks** | ✅ 100% | No external communication |
261
+ | **No uncontrolled memory growth** | ⚠️ Partial | Application must set size limits |
262
+ | **Type safety** | ✅ 100% | TypeScript prevents type confusion |
263
+ | **Iterator safety** | ✅ 100% | Clear documented behavior |
264
+ | **Protection from invalid input** | ⚠️ Partial | Application validates input |
265
+
266
+ ### What This Library Does NOT Guarantee
267
+
268
+ | Guarantee | Status | Details |
269
+ |-----------|--------|---------|
270
+ | **Constant-time operations** | ❌ No | Timing attacks possible (crypto use only) |
271
+ | **Protection from DoS** | ⚠️ No | Application must rate-limit |
272
+ | **Untrusted input handling** | ❌ No | Input validation is application's responsibility |
273
+ | **Secure random numbers** | ❌ No | Not applicable (no randomness) |
274
+ | **Cryptographic security** | ❌ No | Not a crypto library |
275
+
276
+ ---
277
+
278
+ ## Input Validation
279
+
280
+ ### Comparators Must Be Pure
281
+
282
+ **Unsafe: Side effects or external state**
283
+
284
+ ```typescript
285
+ // ❌ DO NOT DO THIS
286
+ let callCount = 0;
287
+ const tree = new RedBlackTree<number>((a, b) => {
288
+ callCount++; // Side effect!
289
+ return a - b;
290
+ });
291
+
292
+ // ❌ DO NOT DO THIS
293
+ const config = getConfig();
294
+ const tree = new RedBlackTree<number>((a, b) => {
295
+ const weight = config.weight; // Mutable external state
296
+ return (a - b) * weight;
297
+ });
298
+
299
+ // ✅ DO THIS
300
+ const tree = new RedBlackTree<number>((a, b) => {
301
+ return a - b; // Pure function
302
+ });
303
+
304
+ const weightedTree = new RedBlackTree<number>((a, b) => {
305
+ return (a - b) * FIXED_WEIGHT; // Fixed constant
306
+ });
307
+ ```
308
+
309
+ ### Validate Comparators Upfront
310
+
311
+ ```typescript
312
+ // ✅ Validate comparator before using
313
+ function validateComparator<T>(comp: (a: T, b: T) => number, samples: T[]): boolean {
314
+ for (let i = 0; i < samples.length; i++) {
315
+ for (let j = i + 1; j < samples.length; j++) {
316
+ const result = comp(samples[i], samples[j]);
317
+
318
+ // Comparator must return -1, 0, or 1 (or at least consistent)
319
+ if (Math.abs(result) > 1 && result !== 0) {
320
+ return false; // Invalid comparator
321
+ }
322
+
323
+ // Transitivity check
324
+ for (let k = j + 1; k < samples.length; k++) {
325
+ const ij = comp(samples[i], samples[j]);
326
+ const jk = comp(samples[j], samples[k]);
327
+ const ik = comp(samples[i], samples[k]);
328
+
329
+ if (!isTransitive(ij, jk, ik)) {
330
+ return false; // Comparator violates transitivity
331
+ }
332
+ }
333
+ }
334
+ }
335
+ return true;
336
+ }
337
+
338
+ // Use validated comparator
339
+ const myComparator = (a: number, b: number) => a - b;
340
+ if (!validateComparator(myComparator, [1, 2, 3])) {
341
+ throw new Error('Invalid comparator');
342
+ }
343
+
344
+ const tree = new RedBlackTree<number>(myComparator);
345
+ ```
346
+
347
+ ### Bound Structure Size
348
+
349
+ ```typescript
350
+ // ✅ Enforce maximum size
351
+ class BoundedTree<K, V> extends RedBlackTree<K, V> {
352
+ private maxSize: number;
353
+
354
+ constructor(maxSize: number = 100000) {
355
+ super();
356
+ this.maxSize = maxSize;
357
+ }
358
+
359
+ set(key: K, value: V): this {
360
+ if (this.size >= this.maxSize && !this.has(key)) {
361
+ throw new Error(`Tree exceeds max size of ${this.maxSize}`);
362
+ }
363
+ return super.set(key, value);
364
+ }
365
+ }
366
+
367
+ // Use with confidence
368
+ const tree = new BoundedTree(10000);
369
+ ```
370
+
371
+ ---
372
+
373
+ ## Comparator Safety
374
+
375
+ ### Comparator Requirements
376
+
377
+ **A valid comparator must:**
378
+
379
+ 1. **Return consistent values**
380
+ ```typescript
381
+ const comp = (a, b) => {
382
+ // ✅ Always returns same value for same inputs
383
+ return a - b;
384
+ };
385
+ ```
386
+
387
+ 2. **Respect transitivity**
388
+ ```typescript
389
+ // If a < b and b < c, then a < c
390
+ const a = 1, b = 2, c = 3;
391
+ comp(a, b) < 0 // true
392
+ comp(b, c) < 0 // true
393
+ comp(a, c) < 0 // must be true
394
+ ```
395
+
396
+ 3. **Handle all input types**
397
+ ```typescript
398
+ const comp = (a, b) => {
399
+ // Handle null, undefined, NaN
400
+ if (a == null || b == null) return 0;
401
+ if (isNaN(a) || isNaN(b)) return 0;
402
+ return a - b;
403
+ };
404
+ ```
405
+
406
+ ### Dangerous Comparators
407
+
408
+ ```typescript
409
+ // ❌ DO NOT: Random comparators
410
+ const random = (a, b) => Math.random() - 0.5;
411
+
412
+ // ❌ DO NOT: Non-deterministic
413
+ const nonDet = (() => {
414
+ let x = 0;
415
+ return (a, b) => (x++, a - b);
416
+ })();
417
+
418
+ // ❌ DO NOT: Side effects
419
+ const withSideEffect = (a, b) => {
420
+ console.log(a, b); // Side effect
421
+ return a - b;
422
+ };
423
+
424
+ // ❌ DO NOT: Throwing errors
425
+ const throws = (a, b) => {
426
+ throw new Error('Oops');
427
+ };
428
+
429
+ // ❌ DO NOT: Inconsistent logic
430
+ const inconsistent = (a, b) => {
431
+ return Math.random() > 0.5 ? a - b : b - a;
432
+ };
433
+ ```
434
+
435
+ ---
436
+
437
+ ## Memory Management
438
+
439
+ ### Structure Lifecycle
440
+
441
+ ```typescript
442
+ // ✅ Proper lifecycle management
443
+
444
+ // 1. Create with expected size
445
+ const tree = new RedBlackTree<number, object>();
446
+
447
+ // 2. Add items
448
+ for (const item of items) {
449
+ tree.set(item.id, item);
450
+ }
451
+
452
+ // 3. Use structure
453
+ const value = tree.get(key);
454
+
455
+ // 4. Clean up when done
456
+ tree.clear(); // O(n) operation
457
+
458
+ // 5. Allow garbage collection
459
+ tree = null; // Or let it go out of scope
460
+ ```
461
+
462
+ ### Garbage Collection
463
+
464
+ **Library does NOT prevent garbage collection:**
465
+
466
+ ```typescript
467
+ // JavaScript will GC unused structures
468
+ {
469
+ const tree = new RedBlackTree();
470
+ tree.addMany([...]);
471
+ // tree goes out of scope
472
+ // JavaScript automatically frees memory
473
+ }
474
+
475
+ // For browser memory management
476
+ function processLargeDataset() {
477
+ const tree = new RedBlackTree();
478
+
479
+ try {
480
+ // Process data
481
+ for (const item of dataset) {
482
+ tree.set(item.id, item);
483
+ }
484
+ return tree.size;
485
+ } finally {
486
+ tree.clear(); // Explicit cleanup
487
+ }
488
+ }
489
+ ```
490
+
491
+ ### Node References
492
+
493
+ **Be careful with cached references:**
494
+
495
+ ```typescript
496
+ // ❌ Potential memory leak
497
+ const nodes = [];
498
+ for (const item of items) {
499
+ const node = tree.getNode(item.id);
500
+ nodes.push(node); // Keeps reference
501
+ }
502
+
503
+ // Tree nodes hold references to their neighbors
504
+ // This prevents garbage collection
505
+
506
+ // ✅ Don't keep references to internal nodes
507
+ for (const item of items) {
508
+ const value = tree.get(item.id); // Get value, not node
509
+ // Process value
510
+ }
511
+ ```
512
+
513
+ ---
514
+
515
+ ## Type Safety
516
+
517
+ ### Strict TypeScript Configuration
518
+
519
+ **Recommended tsconfig.json:**
520
+
521
+ ```json
522
+ {
523
+ "compilerOptions": {
524
+ "strict": true,
525
+ "strictNullChecks": true,
526
+ "strictFunctionTypes": true,
527
+ "strictPropertyInitialization": true,
528
+ "strictBindCallApply": true,
529
+ "alwaysStrict": true,
530
+ "noImplicitAny": true,
531
+ "noImplicitThis": true,
532
+ "noImplicitReturns": true,
533
+ "noFallthroughCasesInSwitch": true,
534
+ "noImplicitReturns": true
535
+ }
536
+ }
537
+ ```
538
+
539
+ ### Type-Safe Usage
540
+
541
+ ```typescript
542
+ // ✅ Type-safe
543
+ const tree = new RedBlackTree<number, string>();
544
+ tree.set(1, 'Alice');
545
+ const name = tree.get(1); // Type: string | undefined
546
+
547
+ // ❌ Unsafe (avoided with strict mode)
548
+ const anyTree = new RedBlackTree() as any;
549
+ anyTree.set('wrong type', 123); // TypeScript won't catch this
550
+ ```
551
+
552
+ ### Generic Constraints
553
+
554
+ ```typescript
555
+ // ✅ Constrain types
556
+ interface Comparable {
557
+ compareTo(other: this): number;
558
+ }
559
+
560
+ const tree = new RedBlackTree<Comparable>((a, b) => {
561
+ return a.compareTo(b);
562
+ });
563
+
564
+ // ✅ Union types for flexibility
565
+ type ValidKey = number | string | symbol;
566
+ const tree = new RedBlackTree<ValidKey, unknown>();
567
+ ```
568
+
569
+ ---
570
+
571
+ ## Iteration Safety
572
+
573
+ ### Safe Iteration Patterns
574
+
575
+ **Pattern 1: Snapshot before mutation**
576
+
577
+ ```typescript
578
+ // ✅ SAFE: Create snapshot first
579
+ const tree = new RedBlackTree([1, 2, 3, 4, 5]);
580
+
581
+ const items = [...tree]; // Snapshot
582
+ items.forEach(item => {
583
+ tree.delete(item); // Safe to mutate now
584
+ });
585
+ ```
586
+
587
+ **Pattern 2: Collect then apply**
588
+
589
+ ```typescript
590
+ // ✅ SAFE: Collect mutations first
591
+ const tree = new RedBlackTree([1, 2, 3, 4, 5]);
592
+
593
+ const toDelete = [];
594
+ for (const item of tree) {
595
+ if (shouldDelete(item)) {
596
+ toDelete.push(item);
597
+ }
598
+ }
599
+
600
+ toDelete.forEach(item => tree.delete(item)); // Apply mutations
601
+ ```
602
+
603
+ **Pattern 3: Functional approach**
604
+
605
+ ```typescript
606
+ // ✅ SAFE: Functional transformations
607
+ const tree = new RedBlackTree([1, 2, 3, 4, 5]);
608
+
609
+ const filtered = tree
610
+ .filter(x => x > 2)
611
+ .map(x => x * 2);
612
+
613
+ // Result is new structure, original unchanged
614
+ ```
615
+
616
+ ### Unsafe Iteration
617
+
618
+ ```typescript
619
+ // ❌ DO NOT DO THIS
620
+ const tree = new RedBlackTree([1, 2, 3]);
621
+
622
+ for (const item of tree) {
623
+ if (condition(item)) {
624
+ tree.delete(item); // Undefined behavior!
625
+ }
626
+ }
627
+
628
+ // ❌ DO NOT DO THIS
629
+ const tree = new RedBlackTree([1, 2, 3]);
630
+
631
+ [...tree].forEach(item => {
632
+ tree.set(item, 'new'); // May cause issues
633
+ });
634
+ ```
635
+
636
+ ---
637
+
638
+ ## Denial of Service (DoS) Protection
639
+
640
+ ### Attack Vector: Expensive Comparisons
641
+
642
+ **Risk:** Comparator is very slow
643
+
644
+ ```typescript
645
+ // ❌ Attacker provides slow comparator
646
+ const tree = new RedBlackTree<number>((a, b) => {
647
+ // Simulate expensive operation
648
+ for (let i = 0; i < 1000000; i++) {
649
+ Math.sqrt(i);
650
+ }
651
+ return a - b;
652
+ });
653
+
654
+ tree.addMany([...1000 items...]); // Takes forever
655
+ ```
656
+
657
+ **Mitigation:**
658
+
659
+ ```typescript
660
+ // ✅ Set timeout for tree operations
661
+ function withTimeout<T>(fn: () => T, timeoutMs: number): T {
662
+ const start = Date.now();
663
+ const result = fn();
664
+
665
+ if (Date.now() - start > timeoutMs) {
666
+ throw new Error('Tree operation exceeded timeout');
667
+ }
668
+
669
+ return result;
670
+ }
671
+
672
+ // Usage
673
+ withTimeout(() => tree.addMany(items), 1000);
674
+ ```
675
+
676
+ ### Attack Vector: Hash Collision
677
+
678
+ **Risk:** Malicious keys cause hash-like collisions
679
+
680
+ ```typescript
681
+ // This is not applicable to comparison-based trees
682
+ // Skip lists and other hash-based structures at risk
683
+ ```
684
+
685
+ ### Attack Vector: Stack Overflow
686
+
687
+ **Risk:** Very deep recursive structure
688
+
689
+ ```typescript
690
+ // ❌ Create deeply unbalanced tree (if using unbalanced BST)
691
+ const bst = new BST();
692
+ for (let i = 0; i < 10000; i++) {
693
+ bst.add(i); // Creates linear chain, not balanced tree
694
+ }
695
+
696
+ // For balanced trees (RedBlackTree, AVLTree):
697
+ // ✅ Automatically balanced
698
+ const rbTree = new RedBlackTree();
699
+ for (let i = 0; i < 10000; i++) {
700
+ rbTree.set(i, i); // Always balanced, logarithmic depth
701
+ }
702
+ ```
703
+
704
+ ---
705
+
706
+ ## Dependency Security
707
+
708
+ ### No Runtime Dependencies
709
+
710
+ ✅ **Zero runtime dependencies**
711
+
712
+ ```json
713
+ {
714
+ "name": "data-structure-typed",
715
+ "dependencies": {},
716
+ "devDependencies": {
717
+ "typescript": "^5.0.0",
718
+ "jest": "^29.0.0"
719
+ }
720
+ }
721
+ ```
722
+
723
+ **Benefit:**
724
+ - No supply chain attacks from dependencies
725
+ - No security updates needed for dependencies
726
+ - Smaller bundle size
727
+ - No transitive dependency issues
728
+
729
+ ### Development Dependencies
730
+
731
+ All dev dependencies are security-audited:
732
+
733
+ ```bash
734
+ npm audit # Always clean (zero vulnerabilities)
735
+ ```
736
+
737
+ ---
738
+
739
+ ## Secure Usage Patterns
740
+
741
+ ### Pattern 1: Bounded Collections
742
+
743
+ ```typescript
744
+ class SafeTree<K, V> extends RedBlackTree<K, V> {
745
+ private readonly maxSize: number;
746
+
747
+ constructor(maxSize: number = 100000) {
748
+ super();
749
+ this.maxSize = maxSize;
750
+ }
751
+
752
+ set(key: K, value: V): this {
753
+ if (this.size >= this.maxSize && !this.has(key)) {
754
+ throw new Error(`Collection exceeds max size: ${this.maxSize}`);
755
+ }
756
+ return super.set(key, value);
757
+ }
758
+ }
759
+ ```
760
+
761
+ ### Pattern 2: Validated Input
762
+
763
+ ```typescript
764
+ function processUntrustedData(data: unknown): void {
765
+ // 1. Validate structure
766
+ if (!isArray(data)) {
767
+ throw new TypeError('Expected array');
768
+ }
769
+
770
+ // 2. Validate items
771
+ const validItems = data.filter(isValidItem);
772
+
773
+ // 3. Use in structure
774
+ const tree = new RedBlackTree<number, string>();
775
+
776
+ for (const item of validItems) {
777
+ tree.set(item.id, item.name);
778
+ }
779
+ }
780
+
781
+ function isValidItem(item: unknown): item is { id: number; name: string } {
782
+ return (
783
+ typeof item === 'object' &&
784
+ item !== null &&
785
+ typeof (item as any).id === 'number' &&
786
+ typeof (item as any).name === 'string'
787
+ );
788
+ }
789
+ ```
790
+
791
+ ### Pattern 3: Timeout Protection
792
+
793
+ ```typescript
794
+ async function processWithTimeout<T>(
795
+ fn: () => T,
796
+ timeoutMs: number
797
+ ): Promise<T> {
798
+ return Promise.race([
799
+ Promise.resolve(fn()),
800
+ new Promise<never>((_, reject) =>
801
+ setTimeout(() => reject(new Error('Timeout')), timeoutMs)
802
+ )
803
+ ]);
804
+ }
805
+
806
+ // Usage
807
+ const tree = new RedBlackTree();
808
+ await processWithTimeout(() => {
809
+ tree.addMany(items);
810
+ }, 5000); // 5 second timeout
811
+ ```
812
+
813
+ ### Pattern 4: Snapshot Operations
814
+
815
+ ```typescript
816
+ function batchDelete<K, V>(
817
+ tree: RedBlackTree<K, V>,
818
+ predicate: (v: V, k?: K) => boolean
819
+ ): number {
820
+ const snapshot = [...tree.entries()];
821
+ let deleted = 0;
822
+
823
+ for (const [key, value] of snapshot) {
824
+ if (predicate(value, key)) {
825
+ if (tree.delete(key)) {
826
+ deleted++;
827
+ }
828
+ }
829
+ }
830
+
831
+ return deleted;
832
+ }
833
+ ```
834
+
835
+ ---
836
+
837
+ ## Known Limitations
838
+
839
+ ### Timing Attacks
840
+
841
+ **Library is NOT constant-time:**
842
+
843
+ ```typescript
844
+ // Search time depends on tree depth (logarithmic but variable)
845
+ tree.get(key); // May take different times
846
+
847
+ // Use only in non-cryptographic contexts
848
+ // DO NOT use for cryptographic key storage
849
+ ```
850
+
851
+ ### Stack Depth
852
+
853
+ **Very large structures may cause stack issues with recursion-based operations:**
854
+
855
+ ```typescript
856
+ // ❌ Risk: Deep tree with DFS
857
+ const largeTree = new RedBlackTree();
858
+ for (let i = 0; i < 1000000; i++) {
859
+ largeTree.set(i, i); // Very deep tree possible
860
+ }
861
+
862
+ // RedBlackTree maintains O(log n) depth, so safe
863
+ // BST without balancing could reach O(n) depth
864
+ ```
865
+
866
+ ### Weak Comparators
867
+
868
+ **Library trusts provided comparators:**
869
+
870
+ ```typescript
871
+ // ❌ User error: Bad comparator
872
+ const tree = new RedBlackTree((a, b) => {
873
+ return Math.random() - 0.5; // Random!
874
+ });
875
+
876
+ // Library assumes comparator is deterministic
877
+ // User responsibility to provide valid comparator
878
+ ```
879
+
880
+ ---
881
+
882
+ ## Security Update Policy
883
+
884
+ ### Reporting Vulnerabilities
885
+
886
+ **DO NOT open public GitHub issues for security vulnerabilities.**
887
+
888
+ Instead:
889
+ 1. Email: security@example.com (if applicable)
890
+ 2. Or use GitHub Security Advisories private reporting
891
+ 3. Include: Description, Impact, Proof of Concept, Suggested Fix
892
+
893
+ ### Response Timeline
894
+
895
+ - **Day 0**: Initial acknowledgment
896
+ - **Day 1-3**: Triage and impact assessment
897
+ - **Day 3-7**: Fix development
898
+ - **Day 7-14**: Testing and validation
899
+ - **Day 14**: Security release published
900
+
901
+ ### Disclosure Policy
902
+
903
+ **Responsible Disclosure:**
904
+ - 90-day embargo before public disclosure
905
+ - Fix released before public announcement
906
+ - Credit to reporter (if desired)
907
+ - CVE assignment for critical issues
908
+
909
+ ### Patch Release Schedule
910
+
911
+ Security patches released immediately as:
912
+ - **2.0.x** - Current stable version
913
+ - **1.x.x** - Extended support (if applicable)
914
+
915
+ ---
916
+
917
+ ## Security Checklist
918
+
919
+ ### For Library Developers
920
+
921
+ - ✅ Run `npm audit` regularly
922
+ - ✅ Keep TypeScript updated
923
+ - ✅ Review all public APIs
924
+ - ✅ Test error handling
925
+ - ✅ Document security considerations
926
+ - ✅ Monitor GitHub Security Advisories
927
+
928
+ ### For Library Users
929
+
930
+ - ✅ Use strict TypeScript (`strict: true`)
931
+ - ✅ Validate all external input
932
+ - ✅ Bound structure sizes
933
+ - ✅ Don't mutate during iteration
934
+ - ✅ Provide valid, pure comparators
935
+ - ✅ Keep TypeScript updated
936
+
937
+ ---
938
+
939
+ ## Additional Resources
940
+
941
+ - **[SPECIFICATION.md](./SPECIFICATION.md)** - Technical specifications
942
+ - **[ARCHITECTURE.md](./ARCHITECTURE.md)** - Design decisions
943
+ - **[PERFORMANCE.md](./PERFORMANCE.md)** - Performance characteristics
944
+ - **[GUIDES.md](./GUIDES.md)** - Usage examples
945
+ - **OWASP** - https://owasp.org (security best practices)
946
+ - **CWE** - https://cwe.mitre.org (weakness taxonomy)
947
+
948
+ ---
949
+
950
+ ## Summary
951
+
952
+ **data-structure-typed is secure for general-purpose use with these principles:**
953
+
954
+ 1. **Trust TypeScript** - Use strict mode for type safety
955
+ 2. **Bound Inputs** - Enforce maximum sizes at application level
956
+ 3. **Validate Comparators** - Ensure they're pure and deterministic
957
+ 4. **Snapshot Mutations** - Never mutate during iteration
958
+ 5. **Monitor Usage** - Track structure sizes and operation times
959
+
960
+ **For cryptographic security:** This is NOT the right library. Use dedicated crypto libraries like TweetNaCl.js, libsodium, or crypto-js.
961
+
962
+ ---
963
+
964
+ **Maintained By:** [@zrwusa](https://github.com/zrwusa)
965
+ **License:** MIT
966
+ **Last Updated:** January 2026