@claude-flow/security 3.0.0-alpha.1 → 3.0.0-alpha.11
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 +292 -234
- package/__tests__/acceptance/security-compliance.test.ts +674 -674
- package/__tests__/authorization-propagator.test.ts +155 -0
- package/__tests__/credential-generator.test.ts +310 -310
- package/__tests__/fixtures/configurations.ts +425 -419
- package/__tests__/fixtures/index.ts +21 -21
- package/__tests__/helpers/create-mock.ts +469 -469
- package/__tests__/helpers/index.ts +32 -32
- package/__tests__/input-validator.test.ts +382 -381
- package/__tests__/integration/security-flow.test.ts +606 -606
- package/__tests__/keychain-adapter.test.ts +60 -0
- package/__tests__/oauth-browser.test.ts +13 -0
- package/__tests__/oauth-export-surface.test.ts +21 -0
- package/__tests__/oauth-pkce.test.ts +37 -0
- package/__tests__/password-hasher.test.ts +239 -239
- package/__tests__/path-validator.test.ts +302 -302
- package/__tests__/plugin-integrity-verifier.test.ts +199 -0
- package/__tests__/safe-executor.test.ts +292 -292
- package/__tests__/token-generator.test.ts +371 -371
- package/__tests__/tool-output-guardrail.test.ts +256 -0
- package/__tests__/unit/credential-generator.test.ts +182 -182
- package/__tests__/unit/password-hasher.test.ts +359 -359
- package/__tests__/unit/path-validator.test.ts +509 -509
- package/__tests__/unit/safe-executor.test.ts +667 -667
- package/__tests__/unit/token-generator.test.ts +310 -310
- package/dist/CVE-REMEDIATION.d.ts +17 -6
- package/dist/CVE-REMEDIATION.d.ts.map +1 -1
- package/dist/CVE-REMEDIATION.js +328 -12
- package/dist/CVE-REMEDIATION.js.map +1 -1
- package/dist/authorization/propagator.d.ts +148 -0
- package/dist/authorization/propagator.d.ts.map +1 -0
- package/dist/authorization/propagator.js +182 -0
- package/dist/authorization/propagator.js.map +1 -0
- package/dist/credential-generator.js +9 -9
- package/dist/domain/services/security-domain-service.js +1 -1
- package/dist/domain/services/security-domain-service.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -1
- package/dist/index.js.map +1 -1
- package/dist/keychain-adapter.d.ts +48 -0
- package/dist/keychain-adapter.d.ts.map +1 -0
- package/dist/keychain-adapter.js +0 -0
- package/dist/keychain-adapter.js.map +1 -0
- package/dist/oauth/browser.d.ts +31 -0
- package/dist/oauth/browser.d.ts.map +1 -0
- package/dist/oauth/browser.js +55 -0
- package/dist/oauth/browser.js.map +1 -0
- package/dist/oauth/callback-server.d.ts +37 -0
- package/dist/oauth/callback-server.d.ts.map +1 -0
- package/dist/oauth/callback-server.js +86 -0
- package/dist/oauth/callback-server.js.map +1 -0
- package/dist/oauth/client.d.ts +57 -0
- package/dist/oauth/client.d.ts.map +1 -0
- package/dist/oauth/client.js +120 -0
- package/dist/oauth/client.js.map +1 -0
- package/dist/oauth/pkce.d.ts +25 -0
- package/dist/oauth/pkce.d.ts.map +1 -0
- package/dist/oauth/pkce.js +36 -0
- package/dist/oauth/pkce.js.map +1 -0
- package/dist/password-hasher.d.ts.map +1 -1
- package/dist/password-hasher.js +8 -1
- package/dist/password-hasher.js.map +1 -1
- package/dist/plugins/integrity-verifier.d.ts +125 -0
- package/dist/plugins/integrity-verifier.d.ts.map +1 -0
- package/dist/plugins/integrity-verifier.js +186 -0
- package/dist/plugins/integrity-verifier.js.map +1 -0
- package/dist/safe-executor.d.ts +7 -0
- package/dist/safe-executor.d.ts.map +1 -1
- package/dist/safe-executor.js +21 -1
- package/dist/safe-executor.js.map +1 -1
- package/dist/tool-output-guardrail.d.ts +126 -0
- package/dist/tool-output-guardrail.d.ts.map +1 -0
- package/dist/tool-output-guardrail.js +257 -0
- package/dist/tool-output-guardrail.js.map +1 -0
- package/node_modules-incomplete-release-test/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/package.json +33 -28
- package/scripts/verify-oauth-exports.mjs +29 -0
- package/src/CVE-REMEDIATION.ts +591 -251
- package/src/application/index.ts +10 -10
- package/src/application/services/security-application-service.ts +193 -193
- package/src/authorization/propagator.ts +279 -0
- package/src/credential-generator.ts +368 -368
- package/src/domain/entities/security-context.ts +173 -173
- package/src/domain/index.ts +17 -17
- package/src/domain/services/security-domain-service.ts +296 -296
- package/src/index.ts +340 -271
- package/src/input-validator.ts +466 -466
- package/src/keychain-adapter.ts +0 -0
- package/src/oauth/browser.ts +58 -0
- package/src/oauth/callback-server.ts +97 -0
- package/src/oauth/client.ts +153 -0
- package/src/oauth/pkce.ts +45 -0
- package/src/password-hasher.ts +277 -270
- package/src/path-validator.ts +525 -525
- package/src/plugins/integrity-verifier.ts +265 -0
- package/src/safe-executor.ts +546 -525
- package/src/token-generator.ts +463 -463
- package/src/tool-output-guardrail.ts +360 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -9
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +20 -0
- package/.agentic-flow/intelligence.json +0 -16
- package/__tests__/coverage/base.css +0 -224
- package/__tests__/coverage/block-navigation.js +0 -87
- package/__tests__/coverage/coverage-final.json +0 -11
- package/__tests__/coverage/favicon.png +0 -0
- package/__tests__/coverage/index.html +0 -161
- package/__tests__/coverage/lcov-report/base.css +0 -224
- package/__tests__/coverage/lcov-report/block-navigation.js +0 -87
- package/__tests__/coverage/lcov-report/favicon.png +0 -0
- package/__tests__/coverage/lcov-report/index.html +0 -161
- package/__tests__/coverage/lcov-report/prettify.css +0 -1
- package/__tests__/coverage/lcov-report/prettify.js +0 -2
- package/__tests__/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/__tests__/coverage/lcov-report/sorter.js +0 -210
- package/__tests__/coverage/lcov-report/src/CVE-REMEDIATION.ts.html +0 -838
- package/__tests__/coverage/lcov-report/src/application/services/index.html +0 -116
- package/__tests__/coverage/lcov-report/src/application/services/security-application-service.ts.html +0 -664
- package/__tests__/coverage/lcov-report/src/credential-generator.ts.html +0 -1189
- package/__tests__/coverage/lcov-report/src/domain/entities/index.html +0 -116
- package/__tests__/coverage/lcov-report/src/domain/entities/security-context.ts.html +0 -604
- package/__tests__/coverage/lcov-report/src/domain/services/index.html +0 -116
- package/__tests__/coverage/lcov-report/src/domain/services/security-domain-service.ts.html +0 -973
- package/__tests__/coverage/lcov-report/src/index.html +0 -206
- package/__tests__/coverage/lcov-report/src/input-validator.ts.html +0 -1483
- package/__tests__/coverage/lcov-report/src/password-hasher.ts.html +0 -895
- package/__tests__/coverage/lcov-report/src/path-validator.ts.html +0 -1660
- package/__tests__/coverage/lcov-report/src/safe-executor.ts.html +0 -1660
- package/__tests__/coverage/lcov-report/src/token-generator.ts.html +0 -1474
- package/__tests__/coverage/lcov.info +0 -3650
- package/__tests__/coverage/prettify.css +0 -1
- package/__tests__/coverage/prettify.js +0 -2
- package/__tests__/coverage/sort-arrow-sprite.png +0 -0
- package/__tests__/coverage/sorter.js +0 -210
- package/__tests__/coverage/src/CVE-REMEDIATION.ts.html +0 -838
- package/__tests__/coverage/src/application/services/index.html +0 -116
- package/__tests__/coverage/src/application/services/security-application-service.ts.html +0 -664
- package/__tests__/coverage/src/credential-generator.ts.html +0 -1189
- package/__tests__/coverage/src/domain/entities/index.html +0 -116
- package/__tests__/coverage/src/domain/entities/security-context.ts.html +0 -604
- package/__tests__/coverage/src/domain/services/index.html +0 -116
- package/__tests__/coverage/src/domain/services/security-domain-service.ts.html +0 -973
- package/__tests__/coverage/src/index.html +0 -206
- package/__tests__/coverage/src/input-validator.ts.html +0 -1483
- package/__tests__/coverage/src/password-hasher.ts.html +0 -895
- package/__tests__/coverage/src/path-validator.ts.html +0 -1660
- package/__tests__/coverage/src/safe-executor.ts.html +0 -1660
- package/__tests__/coverage/src/token-generator.ts.html +0 -1474
|
@@ -1,1660 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
<!doctype html>
|
|
3
|
-
<html lang="en">
|
|
4
|
-
|
|
5
|
-
<head>
|
|
6
|
-
<title>Code coverage report for src/path-validator.ts</title>
|
|
7
|
-
<meta charset="utf-8" />
|
|
8
|
-
<link rel="stylesheet" href="../prettify.css" />
|
|
9
|
-
<link rel="stylesheet" href="../base.css" />
|
|
10
|
-
<link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
|
|
11
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
-
<style type='text/css'>
|
|
13
|
-
.coverage-summary .sorter {
|
|
14
|
-
background-image: url(../sort-arrow-sprite.png);
|
|
15
|
-
}
|
|
16
|
-
</style>
|
|
17
|
-
</head>
|
|
18
|
-
|
|
19
|
-
<body>
|
|
20
|
-
<div class='wrapper'>
|
|
21
|
-
<div class='pad1'>
|
|
22
|
-
<h1><a href="../index.html">All files</a> / <a href="index.html">src</a> path-validator.ts</h1>
|
|
23
|
-
<div class='clearfix'>
|
|
24
|
-
|
|
25
|
-
<div class='fl pad1y space-right2'>
|
|
26
|
-
<span class="strong">0% </span>
|
|
27
|
-
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>0/525</span>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">0% </span>
|
|
34
|
-
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>0/1</span>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<div class='fl pad1y space-right2'>
|
|
40
|
-
<span class="strong">0% </span>
|
|
41
|
-
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>0/1</span>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<div class='fl pad1y space-right2'>
|
|
47
|
-
<span class="strong">0% </span>
|
|
48
|
-
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>0/525</span>
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</div>
|
|
54
|
-
<p class="quiet">
|
|
55
|
-
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
-
</p>
|
|
57
|
-
<template id="filterTemplate">
|
|
58
|
-
<div class="quiet">
|
|
59
|
-
Filter:
|
|
60
|
-
<input type="search" id="fileSearch">
|
|
61
|
-
</div>
|
|
62
|
-
</template>
|
|
63
|
-
</div>
|
|
64
|
-
<div class='status-line low'></div>
|
|
65
|
-
<pre><table class="coverage">
|
|
66
|
-
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
-
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
-
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
-
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
-
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
-
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
-
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
-
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
-
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
-
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
-
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
-
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
-
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
-
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
-
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
-
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
-
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
-
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
-
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
-
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
-
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
-
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
-
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
-
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
-
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
-
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
-
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
-
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
-
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
-
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
-
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
-
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
-
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
-
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
-
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
-
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
-
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
-
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
-
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
-
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
-
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
-
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
-
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
-
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
-
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
-
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
-
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
-
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
-
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
-
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
-
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
-
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
-
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
-
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
-
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
-
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
-
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
-
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
-
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
-
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
-
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
-
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
-
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
-
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
-
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
-
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
-
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
-
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
-
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
-
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
-
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
-
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
-
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
-
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
-
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
-
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
-
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
-
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
-
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
-
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
-
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
-
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
-
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
-
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
-
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
-
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
-
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
-
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
-
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
-
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
-
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
-
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
-
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
-
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
-
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
-
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
-
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
-
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
-
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
-
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
-
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
-
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
-
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
-
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
-
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
-
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
-
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
-
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
-
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
-
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
-
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
-
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
-
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
-
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
-
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
-
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
-
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
-
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
-
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
-
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
-
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
-
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
-
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
-
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
-
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
-
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
-
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
-
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
-
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
-
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
-
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
-
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
-
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
-
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
-
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
-
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
-
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
-
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
-
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
-
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
-
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
-
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
-
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
-
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
-
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
-
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
-
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
-
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
-
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
-
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
-
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
-
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
-
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
-
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
-
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
-
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
-
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
-
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
-
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
-
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
-
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
-
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
-
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
-
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
-
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
-
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
-
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
-
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
-
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
-
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
-
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
-
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
-
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
-
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
-
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
-
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
-
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
-
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
-
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
-
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
-
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
-
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
-
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
-
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
-
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
-
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
-
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
-
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
-
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
-
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
-
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
-
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
-
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
-
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
-
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
-
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
-
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
-
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
-
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
-
<a name='L200'></a><a href='#L200'>200</a>
|
|
266
|
-
<a name='L201'></a><a href='#L201'>201</a>
|
|
267
|
-
<a name='L202'></a><a href='#L202'>202</a>
|
|
268
|
-
<a name='L203'></a><a href='#L203'>203</a>
|
|
269
|
-
<a name='L204'></a><a href='#L204'>204</a>
|
|
270
|
-
<a name='L205'></a><a href='#L205'>205</a>
|
|
271
|
-
<a name='L206'></a><a href='#L206'>206</a>
|
|
272
|
-
<a name='L207'></a><a href='#L207'>207</a>
|
|
273
|
-
<a name='L208'></a><a href='#L208'>208</a>
|
|
274
|
-
<a name='L209'></a><a href='#L209'>209</a>
|
|
275
|
-
<a name='L210'></a><a href='#L210'>210</a>
|
|
276
|
-
<a name='L211'></a><a href='#L211'>211</a>
|
|
277
|
-
<a name='L212'></a><a href='#L212'>212</a>
|
|
278
|
-
<a name='L213'></a><a href='#L213'>213</a>
|
|
279
|
-
<a name='L214'></a><a href='#L214'>214</a>
|
|
280
|
-
<a name='L215'></a><a href='#L215'>215</a>
|
|
281
|
-
<a name='L216'></a><a href='#L216'>216</a>
|
|
282
|
-
<a name='L217'></a><a href='#L217'>217</a>
|
|
283
|
-
<a name='L218'></a><a href='#L218'>218</a>
|
|
284
|
-
<a name='L219'></a><a href='#L219'>219</a>
|
|
285
|
-
<a name='L220'></a><a href='#L220'>220</a>
|
|
286
|
-
<a name='L221'></a><a href='#L221'>221</a>
|
|
287
|
-
<a name='L222'></a><a href='#L222'>222</a>
|
|
288
|
-
<a name='L223'></a><a href='#L223'>223</a>
|
|
289
|
-
<a name='L224'></a><a href='#L224'>224</a>
|
|
290
|
-
<a name='L225'></a><a href='#L225'>225</a>
|
|
291
|
-
<a name='L226'></a><a href='#L226'>226</a>
|
|
292
|
-
<a name='L227'></a><a href='#L227'>227</a>
|
|
293
|
-
<a name='L228'></a><a href='#L228'>228</a>
|
|
294
|
-
<a name='L229'></a><a href='#L229'>229</a>
|
|
295
|
-
<a name='L230'></a><a href='#L230'>230</a>
|
|
296
|
-
<a name='L231'></a><a href='#L231'>231</a>
|
|
297
|
-
<a name='L232'></a><a href='#L232'>232</a>
|
|
298
|
-
<a name='L233'></a><a href='#L233'>233</a>
|
|
299
|
-
<a name='L234'></a><a href='#L234'>234</a>
|
|
300
|
-
<a name='L235'></a><a href='#L235'>235</a>
|
|
301
|
-
<a name='L236'></a><a href='#L236'>236</a>
|
|
302
|
-
<a name='L237'></a><a href='#L237'>237</a>
|
|
303
|
-
<a name='L238'></a><a href='#L238'>238</a>
|
|
304
|
-
<a name='L239'></a><a href='#L239'>239</a>
|
|
305
|
-
<a name='L240'></a><a href='#L240'>240</a>
|
|
306
|
-
<a name='L241'></a><a href='#L241'>241</a>
|
|
307
|
-
<a name='L242'></a><a href='#L242'>242</a>
|
|
308
|
-
<a name='L243'></a><a href='#L243'>243</a>
|
|
309
|
-
<a name='L244'></a><a href='#L244'>244</a>
|
|
310
|
-
<a name='L245'></a><a href='#L245'>245</a>
|
|
311
|
-
<a name='L246'></a><a href='#L246'>246</a>
|
|
312
|
-
<a name='L247'></a><a href='#L247'>247</a>
|
|
313
|
-
<a name='L248'></a><a href='#L248'>248</a>
|
|
314
|
-
<a name='L249'></a><a href='#L249'>249</a>
|
|
315
|
-
<a name='L250'></a><a href='#L250'>250</a>
|
|
316
|
-
<a name='L251'></a><a href='#L251'>251</a>
|
|
317
|
-
<a name='L252'></a><a href='#L252'>252</a>
|
|
318
|
-
<a name='L253'></a><a href='#L253'>253</a>
|
|
319
|
-
<a name='L254'></a><a href='#L254'>254</a>
|
|
320
|
-
<a name='L255'></a><a href='#L255'>255</a>
|
|
321
|
-
<a name='L256'></a><a href='#L256'>256</a>
|
|
322
|
-
<a name='L257'></a><a href='#L257'>257</a>
|
|
323
|
-
<a name='L258'></a><a href='#L258'>258</a>
|
|
324
|
-
<a name='L259'></a><a href='#L259'>259</a>
|
|
325
|
-
<a name='L260'></a><a href='#L260'>260</a>
|
|
326
|
-
<a name='L261'></a><a href='#L261'>261</a>
|
|
327
|
-
<a name='L262'></a><a href='#L262'>262</a>
|
|
328
|
-
<a name='L263'></a><a href='#L263'>263</a>
|
|
329
|
-
<a name='L264'></a><a href='#L264'>264</a>
|
|
330
|
-
<a name='L265'></a><a href='#L265'>265</a>
|
|
331
|
-
<a name='L266'></a><a href='#L266'>266</a>
|
|
332
|
-
<a name='L267'></a><a href='#L267'>267</a>
|
|
333
|
-
<a name='L268'></a><a href='#L268'>268</a>
|
|
334
|
-
<a name='L269'></a><a href='#L269'>269</a>
|
|
335
|
-
<a name='L270'></a><a href='#L270'>270</a>
|
|
336
|
-
<a name='L271'></a><a href='#L271'>271</a>
|
|
337
|
-
<a name='L272'></a><a href='#L272'>272</a>
|
|
338
|
-
<a name='L273'></a><a href='#L273'>273</a>
|
|
339
|
-
<a name='L274'></a><a href='#L274'>274</a>
|
|
340
|
-
<a name='L275'></a><a href='#L275'>275</a>
|
|
341
|
-
<a name='L276'></a><a href='#L276'>276</a>
|
|
342
|
-
<a name='L277'></a><a href='#L277'>277</a>
|
|
343
|
-
<a name='L278'></a><a href='#L278'>278</a>
|
|
344
|
-
<a name='L279'></a><a href='#L279'>279</a>
|
|
345
|
-
<a name='L280'></a><a href='#L280'>280</a>
|
|
346
|
-
<a name='L281'></a><a href='#L281'>281</a>
|
|
347
|
-
<a name='L282'></a><a href='#L282'>282</a>
|
|
348
|
-
<a name='L283'></a><a href='#L283'>283</a>
|
|
349
|
-
<a name='L284'></a><a href='#L284'>284</a>
|
|
350
|
-
<a name='L285'></a><a href='#L285'>285</a>
|
|
351
|
-
<a name='L286'></a><a href='#L286'>286</a>
|
|
352
|
-
<a name='L287'></a><a href='#L287'>287</a>
|
|
353
|
-
<a name='L288'></a><a href='#L288'>288</a>
|
|
354
|
-
<a name='L289'></a><a href='#L289'>289</a>
|
|
355
|
-
<a name='L290'></a><a href='#L290'>290</a>
|
|
356
|
-
<a name='L291'></a><a href='#L291'>291</a>
|
|
357
|
-
<a name='L292'></a><a href='#L292'>292</a>
|
|
358
|
-
<a name='L293'></a><a href='#L293'>293</a>
|
|
359
|
-
<a name='L294'></a><a href='#L294'>294</a>
|
|
360
|
-
<a name='L295'></a><a href='#L295'>295</a>
|
|
361
|
-
<a name='L296'></a><a href='#L296'>296</a>
|
|
362
|
-
<a name='L297'></a><a href='#L297'>297</a>
|
|
363
|
-
<a name='L298'></a><a href='#L298'>298</a>
|
|
364
|
-
<a name='L299'></a><a href='#L299'>299</a>
|
|
365
|
-
<a name='L300'></a><a href='#L300'>300</a>
|
|
366
|
-
<a name='L301'></a><a href='#L301'>301</a>
|
|
367
|
-
<a name='L302'></a><a href='#L302'>302</a>
|
|
368
|
-
<a name='L303'></a><a href='#L303'>303</a>
|
|
369
|
-
<a name='L304'></a><a href='#L304'>304</a>
|
|
370
|
-
<a name='L305'></a><a href='#L305'>305</a>
|
|
371
|
-
<a name='L306'></a><a href='#L306'>306</a>
|
|
372
|
-
<a name='L307'></a><a href='#L307'>307</a>
|
|
373
|
-
<a name='L308'></a><a href='#L308'>308</a>
|
|
374
|
-
<a name='L309'></a><a href='#L309'>309</a>
|
|
375
|
-
<a name='L310'></a><a href='#L310'>310</a>
|
|
376
|
-
<a name='L311'></a><a href='#L311'>311</a>
|
|
377
|
-
<a name='L312'></a><a href='#L312'>312</a>
|
|
378
|
-
<a name='L313'></a><a href='#L313'>313</a>
|
|
379
|
-
<a name='L314'></a><a href='#L314'>314</a>
|
|
380
|
-
<a name='L315'></a><a href='#L315'>315</a>
|
|
381
|
-
<a name='L316'></a><a href='#L316'>316</a>
|
|
382
|
-
<a name='L317'></a><a href='#L317'>317</a>
|
|
383
|
-
<a name='L318'></a><a href='#L318'>318</a>
|
|
384
|
-
<a name='L319'></a><a href='#L319'>319</a>
|
|
385
|
-
<a name='L320'></a><a href='#L320'>320</a>
|
|
386
|
-
<a name='L321'></a><a href='#L321'>321</a>
|
|
387
|
-
<a name='L322'></a><a href='#L322'>322</a>
|
|
388
|
-
<a name='L323'></a><a href='#L323'>323</a>
|
|
389
|
-
<a name='L324'></a><a href='#L324'>324</a>
|
|
390
|
-
<a name='L325'></a><a href='#L325'>325</a>
|
|
391
|
-
<a name='L326'></a><a href='#L326'>326</a>
|
|
392
|
-
<a name='L327'></a><a href='#L327'>327</a>
|
|
393
|
-
<a name='L328'></a><a href='#L328'>328</a>
|
|
394
|
-
<a name='L329'></a><a href='#L329'>329</a>
|
|
395
|
-
<a name='L330'></a><a href='#L330'>330</a>
|
|
396
|
-
<a name='L331'></a><a href='#L331'>331</a>
|
|
397
|
-
<a name='L332'></a><a href='#L332'>332</a>
|
|
398
|
-
<a name='L333'></a><a href='#L333'>333</a>
|
|
399
|
-
<a name='L334'></a><a href='#L334'>334</a>
|
|
400
|
-
<a name='L335'></a><a href='#L335'>335</a>
|
|
401
|
-
<a name='L336'></a><a href='#L336'>336</a>
|
|
402
|
-
<a name='L337'></a><a href='#L337'>337</a>
|
|
403
|
-
<a name='L338'></a><a href='#L338'>338</a>
|
|
404
|
-
<a name='L339'></a><a href='#L339'>339</a>
|
|
405
|
-
<a name='L340'></a><a href='#L340'>340</a>
|
|
406
|
-
<a name='L341'></a><a href='#L341'>341</a>
|
|
407
|
-
<a name='L342'></a><a href='#L342'>342</a>
|
|
408
|
-
<a name='L343'></a><a href='#L343'>343</a>
|
|
409
|
-
<a name='L344'></a><a href='#L344'>344</a>
|
|
410
|
-
<a name='L345'></a><a href='#L345'>345</a>
|
|
411
|
-
<a name='L346'></a><a href='#L346'>346</a>
|
|
412
|
-
<a name='L347'></a><a href='#L347'>347</a>
|
|
413
|
-
<a name='L348'></a><a href='#L348'>348</a>
|
|
414
|
-
<a name='L349'></a><a href='#L349'>349</a>
|
|
415
|
-
<a name='L350'></a><a href='#L350'>350</a>
|
|
416
|
-
<a name='L351'></a><a href='#L351'>351</a>
|
|
417
|
-
<a name='L352'></a><a href='#L352'>352</a>
|
|
418
|
-
<a name='L353'></a><a href='#L353'>353</a>
|
|
419
|
-
<a name='L354'></a><a href='#L354'>354</a>
|
|
420
|
-
<a name='L355'></a><a href='#L355'>355</a>
|
|
421
|
-
<a name='L356'></a><a href='#L356'>356</a>
|
|
422
|
-
<a name='L357'></a><a href='#L357'>357</a>
|
|
423
|
-
<a name='L358'></a><a href='#L358'>358</a>
|
|
424
|
-
<a name='L359'></a><a href='#L359'>359</a>
|
|
425
|
-
<a name='L360'></a><a href='#L360'>360</a>
|
|
426
|
-
<a name='L361'></a><a href='#L361'>361</a>
|
|
427
|
-
<a name='L362'></a><a href='#L362'>362</a>
|
|
428
|
-
<a name='L363'></a><a href='#L363'>363</a>
|
|
429
|
-
<a name='L364'></a><a href='#L364'>364</a>
|
|
430
|
-
<a name='L365'></a><a href='#L365'>365</a>
|
|
431
|
-
<a name='L366'></a><a href='#L366'>366</a>
|
|
432
|
-
<a name='L367'></a><a href='#L367'>367</a>
|
|
433
|
-
<a name='L368'></a><a href='#L368'>368</a>
|
|
434
|
-
<a name='L369'></a><a href='#L369'>369</a>
|
|
435
|
-
<a name='L370'></a><a href='#L370'>370</a>
|
|
436
|
-
<a name='L371'></a><a href='#L371'>371</a>
|
|
437
|
-
<a name='L372'></a><a href='#L372'>372</a>
|
|
438
|
-
<a name='L373'></a><a href='#L373'>373</a>
|
|
439
|
-
<a name='L374'></a><a href='#L374'>374</a>
|
|
440
|
-
<a name='L375'></a><a href='#L375'>375</a>
|
|
441
|
-
<a name='L376'></a><a href='#L376'>376</a>
|
|
442
|
-
<a name='L377'></a><a href='#L377'>377</a>
|
|
443
|
-
<a name='L378'></a><a href='#L378'>378</a>
|
|
444
|
-
<a name='L379'></a><a href='#L379'>379</a>
|
|
445
|
-
<a name='L380'></a><a href='#L380'>380</a>
|
|
446
|
-
<a name='L381'></a><a href='#L381'>381</a>
|
|
447
|
-
<a name='L382'></a><a href='#L382'>382</a>
|
|
448
|
-
<a name='L383'></a><a href='#L383'>383</a>
|
|
449
|
-
<a name='L384'></a><a href='#L384'>384</a>
|
|
450
|
-
<a name='L385'></a><a href='#L385'>385</a>
|
|
451
|
-
<a name='L386'></a><a href='#L386'>386</a>
|
|
452
|
-
<a name='L387'></a><a href='#L387'>387</a>
|
|
453
|
-
<a name='L388'></a><a href='#L388'>388</a>
|
|
454
|
-
<a name='L389'></a><a href='#L389'>389</a>
|
|
455
|
-
<a name='L390'></a><a href='#L390'>390</a>
|
|
456
|
-
<a name='L391'></a><a href='#L391'>391</a>
|
|
457
|
-
<a name='L392'></a><a href='#L392'>392</a>
|
|
458
|
-
<a name='L393'></a><a href='#L393'>393</a>
|
|
459
|
-
<a name='L394'></a><a href='#L394'>394</a>
|
|
460
|
-
<a name='L395'></a><a href='#L395'>395</a>
|
|
461
|
-
<a name='L396'></a><a href='#L396'>396</a>
|
|
462
|
-
<a name='L397'></a><a href='#L397'>397</a>
|
|
463
|
-
<a name='L398'></a><a href='#L398'>398</a>
|
|
464
|
-
<a name='L399'></a><a href='#L399'>399</a>
|
|
465
|
-
<a name='L400'></a><a href='#L400'>400</a>
|
|
466
|
-
<a name='L401'></a><a href='#L401'>401</a>
|
|
467
|
-
<a name='L402'></a><a href='#L402'>402</a>
|
|
468
|
-
<a name='L403'></a><a href='#L403'>403</a>
|
|
469
|
-
<a name='L404'></a><a href='#L404'>404</a>
|
|
470
|
-
<a name='L405'></a><a href='#L405'>405</a>
|
|
471
|
-
<a name='L406'></a><a href='#L406'>406</a>
|
|
472
|
-
<a name='L407'></a><a href='#L407'>407</a>
|
|
473
|
-
<a name='L408'></a><a href='#L408'>408</a>
|
|
474
|
-
<a name='L409'></a><a href='#L409'>409</a>
|
|
475
|
-
<a name='L410'></a><a href='#L410'>410</a>
|
|
476
|
-
<a name='L411'></a><a href='#L411'>411</a>
|
|
477
|
-
<a name='L412'></a><a href='#L412'>412</a>
|
|
478
|
-
<a name='L413'></a><a href='#L413'>413</a>
|
|
479
|
-
<a name='L414'></a><a href='#L414'>414</a>
|
|
480
|
-
<a name='L415'></a><a href='#L415'>415</a>
|
|
481
|
-
<a name='L416'></a><a href='#L416'>416</a>
|
|
482
|
-
<a name='L417'></a><a href='#L417'>417</a>
|
|
483
|
-
<a name='L418'></a><a href='#L418'>418</a>
|
|
484
|
-
<a name='L419'></a><a href='#L419'>419</a>
|
|
485
|
-
<a name='L420'></a><a href='#L420'>420</a>
|
|
486
|
-
<a name='L421'></a><a href='#L421'>421</a>
|
|
487
|
-
<a name='L422'></a><a href='#L422'>422</a>
|
|
488
|
-
<a name='L423'></a><a href='#L423'>423</a>
|
|
489
|
-
<a name='L424'></a><a href='#L424'>424</a>
|
|
490
|
-
<a name='L425'></a><a href='#L425'>425</a>
|
|
491
|
-
<a name='L426'></a><a href='#L426'>426</a>
|
|
492
|
-
<a name='L427'></a><a href='#L427'>427</a>
|
|
493
|
-
<a name='L428'></a><a href='#L428'>428</a>
|
|
494
|
-
<a name='L429'></a><a href='#L429'>429</a>
|
|
495
|
-
<a name='L430'></a><a href='#L430'>430</a>
|
|
496
|
-
<a name='L431'></a><a href='#L431'>431</a>
|
|
497
|
-
<a name='L432'></a><a href='#L432'>432</a>
|
|
498
|
-
<a name='L433'></a><a href='#L433'>433</a>
|
|
499
|
-
<a name='L434'></a><a href='#L434'>434</a>
|
|
500
|
-
<a name='L435'></a><a href='#L435'>435</a>
|
|
501
|
-
<a name='L436'></a><a href='#L436'>436</a>
|
|
502
|
-
<a name='L437'></a><a href='#L437'>437</a>
|
|
503
|
-
<a name='L438'></a><a href='#L438'>438</a>
|
|
504
|
-
<a name='L439'></a><a href='#L439'>439</a>
|
|
505
|
-
<a name='L440'></a><a href='#L440'>440</a>
|
|
506
|
-
<a name='L441'></a><a href='#L441'>441</a>
|
|
507
|
-
<a name='L442'></a><a href='#L442'>442</a>
|
|
508
|
-
<a name='L443'></a><a href='#L443'>443</a>
|
|
509
|
-
<a name='L444'></a><a href='#L444'>444</a>
|
|
510
|
-
<a name='L445'></a><a href='#L445'>445</a>
|
|
511
|
-
<a name='L446'></a><a href='#L446'>446</a>
|
|
512
|
-
<a name='L447'></a><a href='#L447'>447</a>
|
|
513
|
-
<a name='L448'></a><a href='#L448'>448</a>
|
|
514
|
-
<a name='L449'></a><a href='#L449'>449</a>
|
|
515
|
-
<a name='L450'></a><a href='#L450'>450</a>
|
|
516
|
-
<a name='L451'></a><a href='#L451'>451</a>
|
|
517
|
-
<a name='L452'></a><a href='#L452'>452</a>
|
|
518
|
-
<a name='L453'></a><a href='#L453'>453</a>
|
|
519
|
-
<a name='L454'></a><a href='#L454'>454</a>
|
|
520
|
-
<a name='L455'></a><a href='#L455'>455</a>
|
|
521
|
-
<a name='L456'></a><a href='#L456'>456</a>
|
|
522
|
-
<a name='L457'></a><a href='#L457'>457</a>
|
|
523
|
-
<a name='L458'></a><a href='#L458'>458</a>
|
|
524
|
-
<a name='L459'></a><a href='#L459'>459</a>
|
|
525
|
-
<a name='L460'></a><a href='#L460'>460</a>
|
|
526
|
-
<a name='L461'></a><a href='#L461'>461</a>
|
|
527
|
-
<a name='L462'></a><a href='#L462'>462</a>
|
|
528
|
-
<a name='L463'></a><a href='#L463'>463</a>
|
|
529
|
-
<a name='L464'></a><a href='#L464'>464</a>
|
|
530
|
-
<a name='L465'></a><a href='#L465'>465</a>
|
|
531
|
-
<a name='L466'></a><a href='#L466'>466</a>
|
|
532
|
-
<a name='L467'></a><a href='#L467'>467</a>
|
|
533
|
-
<a name='L468'></a><a href='#L468'>468</a>
|
|
534
|
-
<a name='L469'></a><a href='#L469'>469</a>
|
|
535
|
-
<a name='L470'></a><a href='#L470'>470</a>
|
|
536
|
-
<a name='L471'></a><a href='#L471'>471</a>
|
|
537
|
-
<a name='L472'></a><a href='#L472'>472</a>
|
|
538
|
-
<a name='L473'></a><a href='#L473'>473</a>
|
|
539
|
-
<a name='L474'></a><a href='#L474'>474</a>
|
|
540
|
-
<a name='L475'></a><a href='#L475'>475</a>
|
|
541
|
-
<a name='L476'></a><a href='#L476'>476</a>
|
|
542
|
-
<a name='L477'></a><a href='#L477'>477</a>
|
|
543
|
-
<a name='L478'></a><a href='#L478'>478</a>
|
|
544
|
-
<a name='L479'></a><a href='#L479'>479</a>
|
|
545
|
-
<a name='L480'></a><a href='#L480'>480</a>
|
|
546
|
-
<a name='L481'></a><a href='#L481'>481</a>
|
|
547
|
-
<a name='L482'></a><a href='#L482'>482</a>
|
|
548
|
-
<a name='L483'></a><a href='#L483'>483</a>
|
|
549
|
-
<a name='L484'></a><a href='#L484'>484</a>
|
|
550
|
-
<a name='L485'></a><a href='#L485'>485</a>
|
|
551
|
-
<a name='L486'></a><a href='#L486'>486</a>
|
|
552
|
-
<a name='L487'></a><a href='#L487'>487</a>
|
|
553
|
-
<a name='L488'></a><a href='#L488'>488</a>
|
|
554
|
-
<a name='L489'></a><a href='#L489'>489</a>
|
|
555
|
-
<a name='L490'></a><a href='#L490'>490</a>
|
|
556
|
-
<a name='L491'></a><a href='#L491'>491</a>
|
|
557
|
-
<a name='L492'></a><a href='#L492'>492</a>
|
|
558
|
-
<a name='L493'></a><a href='#L493'>493</a>
|
|
559
|
-
<a name='L494'></a><a href='#L494'>494</a>
|
|
560
|
-
<a name='L495'></a><a href='#L495'>495</a>
|
|
561
|
-
<a name='L496'></a><a href='#L496'>496</a>
|
|
562
|
-
<a name='L497'></a><a href='#L497'>497</a>
|
|
563
|
-
<a name='L498'></a><a href='#L498'>498</a>
|
|
564
|
-
<a name='L499'></a><a href='#L499'>499</a>
|
|
565
|
-
<a name='L500'></a><a href='#L500'>500</a>
|
|
566
|
-
<a name='L501'></a><a href='#L501'>501</a>
|
|
567
|
-
<a name='L502'></a><a href='#L502'>502</a>
|
|
568
|
-
<a name='L503'></a><a href='#L503'>503</a>
|
|
569
|
-
<a name='L504'></a><a href='#L504'>504</a>
|
|
570
|
-
<a name='L505'></a><a href='#L505'>505</a>
|
|
571
|
-
<a name='L506'></a><a href='#L506'>506</a>
|
|
572
|
-
<a name='L507'></a><a href='#L507'>507</a>
|
|
573
|
-
<a name='L508'></a><a href='#L508'>508</a>
|
|
574
|
-
<a name='L509'></a><a href='#L509'>509</a>
|
|
575
|
-
<a name='L510'></a><a href='#L510'>510</a>
|
|
576
|
-
<a name='L511'></a><a href='#L511'>511</a>
|
|
577
|
-
<a name='L512'></a><a href='#L512'>512</a>
|
|
578
|
-
<a name='L513'></a><a href='#L513'>513</a>
|
|
579
|
-
<a name='L514'></a><a href='#L514'>514</a>
|
|
580
|
-
<a name='L515'></a><a href='#L515'>515</a>
|
|
581
|
-
<a name='L516'></a><a href='#L516'>516</a>
|
|
582
|
-
<a name='L517'></a><a href='#L517'>517</a>
|
|
583
|
-
<a name='L518'></a><a href='#L518'>518</a>
|
|
584
|
-
<a name='L519'></a><a href='#L519'>519</a>
|
|
585
|
-
<a name='L520'></a><a href='#L520'>520</a>
|
|
586
|
-
<a name='L521'></a><a href='#L521'>521</a>
|
|
587
|
-
<a name='L522'></a><a href='#L522'>522</a>
|
|
588
|
-
<a name='L523'></a><a href='#L523'>523</a>
|
|
589
|
-
<a name='L524'></a><a href='#L524'>524</a>
|
|
590
|
-
<a name='L525'></a><a href='#L525'>525</a>
|
|
591
|
-
<a name='L526'></a><a href='#L526'>526</a></td><td class="line-coverage quiet"><span class="cline-any cline-no"> </span>
|
|
592
|
-
<span class="cline-any cline-no"> </span>
|
|
593
|
-
<span class="cline-any cline-no"> </span>
|
|
594
|
-
<span class="cline-any cline-no"> </span>
|
|
595
|
-
<span class="cline-any cline-no"> </span>
|
|
596
|
-
<span class="cline-any cline-no"> </span>
|
|
597
|
-
<span class="cline-any cline-no"> </span>
|
|
598
|
-
<span class="cline-any cline-no"> </span>
|
|
599
|
-
<span class="cline-any cline-no"> </span>
|
|
600
|
-
<span class="cline-any cline-no"> </span>
|
|
601
|
-
<span class="cline-any cline-no"> </span>
|
|
602
|
-
<span class="cline-any cline-no"> </span>
|
|
603
|
-
<span class="cline-any cline-no"> </span>
|
|
604
|
-
<span class="cline-any cline-no"> </span>
|
|
605
|
-
<span class="cline-any cline-no"> </span>
|
|
606
|
-
<span class="cline-any cline-no"> </span>
|
|
607
|
-
<span class="cline-any cline-no"> </span>
|
|
608
|
-
<span class="cline-any cline-no"> </span>
|
|
609
|
-
<span class="cline-any cline-no"> </span>
|
|
610
|
-
<span class="cline-any cline-no"> </span>
|
|
611
|
-
<span class="cline-any cline-no"> </span>
|
|
612
|
-
<span class="cline-any cline-no"> </span>
|
|
613
|
-
<span class="cline-any cline-no"> </span>
|
|
614
|
-
<span class="cline-any cline-no"> </span>
|
|
615
|
-
<span class="cline-any cline-no"> </span>
|
|
616
|
-
<span class="cline-any cline-no"> </span>
|
|
617
|
-
<span class="cline-any cline-no"> </span>
|
|
618
|
-
<span class="cline-any cline-no"> </span>
|
|
619
|
-
<span class="cline-any cline-no"> </span>
|
|
620
|
-
<span class="cline-any cline-no"> </span>
|
|
621
|
-
<span class="cline-any cline-no"> </span>
|
|
622
|
-
<span class="cline-any cline-no"> </span>
|
|
623
|
-
<span class="cline-any cline-no"> </span>
|
|
624
|
-
<span class="cline-any cline-no"> </span>
|
|
625
|
-
<span class="cline-any cline-no"> </span>
|
|
626
|
-
<span class="cline-any cline-no"> </span>
|
|
627
|
-
<span class="cline-any cline-no"> </span>
|
|
628
|
-
<span class="cline-any cline-no"> </span>
|
|
629
|
-
<span class="cline-any cline-no"> </span>
|
|
630
|
-
<span class="cline-any cline-no"> </span>
|
|
631
|
-
<span class="cline-any cline-no"> </span>
|
|
632
|
-
<span class="cline-any cline-no"> </span>
|
|
633
|
-
<span class="cline-any cline-no"> </span>
|
|
634
|
-
<span class="cline-any cline-no"> </span>
|
|
635
|
-
<span class="cline-any cline-no"> </span>
|
|
636
|
-
<span class="cline-any cline-no"> </span>
|
|
637
|
-
<span class="cline-any cline-no"> </span>
|
|
638
|
-
<span class="cline-any cline-no"> </span>
|
|
639
|
-
<span class="cline-any cline-no"> </span>
|
|
640
|
-
<span class="cline-any cline-no"> </span>
|
|
641
|
-
<span class="cline-any cline-no"> </span>
|
|
642
|
-
<span class="cline-any cline-no"> </span>
|
|
643
|
-
<span class="cline-any cline-no"> </span>
|
|
644
|
-
<span class="cline-any cline-no"> </span>
|
|
645
|
-
<span class="cline-any cline-no"> </span>
|
|
646
|
-
<span class="cline-any cline-no"> </span>
|
|
647
|
-
<span class="cline-any cline-no"> </span>
|
|
648
|
-
<span class="cline-any cline-no"> </span>
|
|
649
|
-
<span class="cline-any cline-no"> </span>
|
|
650
|
-
<span class="cline-any cline-no"> </span>
|
|
651
|
-
<span class="cline-any cline-no"> </span>
|
|
652
|
-
<span class="cline-any cline-no"> </span>
|
|
653
|
-
<span class="cline-any cline-no"> </span>
|
|
654
|
-
<span class="cline-any cline-no"> </span>
|
|
655
|
-
<span class="cline-any cline-no"> </span>
|
|
656
|
-
<span class="cline-any cline-no"> </span>
|
|
657
|
-
<span class="cline-any cline-no"> </span>
|
|
658
|
-
<span class="cline-any cline-no"> </span>
|
|
659
|
-
<span class="cline-any cline-no"> </span>
|
|
660
|
-
<span class="cline-any cline-no"> </span>
|
|
661
|
-
<span class="cline-any cline-no"> </span>
|
|
662
|
-
<span class="cline-any cline-no"> </span>
|
|
663
|
-
<span class="cline-any cline-no"> </span>
|
|
664
|
-
<span class="cline-any cline-no"> </span>
|
|
665
|
-
<span class="cline-any cline-no"> </span>
|
|
666
|
-
<span class="cline-any cline-no"> </span>
|
|
667
|
-
<span class="cline-any cline-no"> </span>
|
|
668
|
-
<span class="cline-any cline-no"> </span>
|
|
669
|
-
<span class="cline-any cline-no"> </span>
|
|
670
|
-
<span class="cline-any cline-no"> </span>
|
|
671
|
-
<span class="cline-any cline-no"> </span>
|
|
672
|
-
<span class="cline-any cline-no"> </span>
|
|
673
|
-
<span class="cline-any cline-no"> </span>
|
|
674
|
-
<span class="cline-any cline-no"> </span>
|
|
675
|
-
<span class="cline-any cline-no"> </span>
|
|
676
|
-
<span class="cline-any cline-no"> </span>
|
|
677
|
-
<span class="cline-any cline-no"> </span>
|
|
678
|
-
<span class="cline-any cline-no"> </span>
|
|
679
|
-
<span class="cline-any cline-no"> </span>
|
|
680
|
-
<span class="cline-any cline-no"> </span>
|
|
681
|
-
<span class="cline-any cline-no"> </span>
|
|
682
|
-
<span class="cline-any cline-no"> </span>
|
|
683
|
-
<span class="cline-any cline-no"> </span>
|
|
684
|
-
<span class="cline-any cline-no"> </span>
|
|
685
|
-
<span class="cline-any cline-no"> </span>
|
|
686
|
-
<span class="cline-any cline-no"> </span>
|
|
687
|
-
<span class="cline-any cline-no"> </span>
|
|
688
|
-
<span class="cline-any cline-no"> </span>
|
|
689
|
-
<span class="cline-any cline-no"> </span>
|
|
690
|
-
<span class="cline-any cline-no"> </span>
|
|
691
|
-
<span class="cline-any cline-no"> </span>
|
|
692
|
-
<span class="cline-any cline-no"> </span>
|
|
693
|
-
<span class="cline-any cline-no"> </span>
|
|
694
|
-
<span class="cline-any cline-no"> </span>
|
|
695
|
-
<span class="cline-any cline-no"> </span>
|
|
696
|
-
<span class="cline-any cline-no"> </span>
|
|
697
|
-
<span class="cline-any cline-no"> </span>
|
|
698
|
-
<span class="cline-any cline-no"> </span>
|
|
699
|
-
<span class="cline-any cline-no"> </span>
|
|
700
|
-
<span class="cline-any cline-no"> </span>
|
|
701
|
-
<span class="cline-any cline-no"> </span>
|
|
702
|
-
<span class="cline-any cline-no"> </span>
|
|
703
|
-
<span class="cline-any cline-no"> </span>
|
|
704
|
-
<span class="cline-any cline-no"> </span>
|
|
705
|
-
<span class="cline-any cline-no"> </span>
|
|
706
|
-
<span class="cline-any cline-no"> </span>
|
|
707
|
-
<span class="cline-any cline-no"> </span>
|
|
708
|
-
<span class="cline-any cline-no"> </span>
|
|
709
|
-
<span class="cline-any cline-no"> </span>
|
|
710
|
-
<span class="cline-any cline-no"> </span>
|
|
711
|
-
<span class="cline-any cline-no"> </span>
|
|
712
|
-
<span class="cline-any cline-no"> </span>
|
|
713
|
-
<span class="cline-any cline-no"> </span>
|
|
714
|
-
<span class="cline-any cline-no"> </span>
|
|
715
|
-
<span class="cline-any cline-no"> </span>
|
|
716
|
-
<span class="cline-any cline-no"> </span>
|
|
717
|
-
<span class="cline-any cline-no"> </span>
|
|
718
|
-
<span class="cline-any cline-no"> </span>
|
|
719
|
-
<span class="cline-any cline-no"> </span>
|
|
720
|
-
<span class="cline-any cline-no"> </span>
|
|
721
|
-
<span class="cline-any cline-no"> </span>
|
|
722
|
-
<span class="cline-any cline-no"> </span>
|
|
723
|
-
<span class="cline-any cline-no"> </span>
|
|
724
|
-
<span class="cline-any cline-no"> </span>
|
|
725
|
-
<span class="cline-any cline-no"> </span>
|
|
726
|
-
<span class="cline-any cline-no"> </span>
|
|
727
|
-
<span class="cline-any cline-no"> </span>
|
|
728
|
-
<span class="cline-any cline-no"> </span>
|
|
729
|
-
<span class="cline-any cline-no"> </span>
|
|
730
|
-
<span class="cline-any cline-no"> </span>
|
|
731
|
-
<span class="cline-any cline-no"> </span>
|
|
732
|
-
<span class="cline-any cline-no"> </span>
|
|
733
|
-
<span class="cline-any cline-no"> </span>
|
|
734
|
-
<span class="cline-any cline-no"> </span>
|
|
735
|
-
<span class="cline-any cline-no"> </span>
|
|
736
|
-
<span class="cline-any cline-no"> </span>
|
|
737
|
-
<span class="cline-any cline-no"> </span>
|
|
738
|
-
<span class="cline-any cline-no"> </span>
|
|
739
|
-
<span class="cline-any cline-no"> </span>
|
|
740
|
-
<span class="cline-any cline-no"> </span>
|
|
741
|
-
<span class="cline-any cline-no"> </span>
|
|
742
|
-
<span class="cline-any cline-no"> </span>
|
|
743
|
-
<span class="cline-any cline-no"> </span>
|
|
744
|
-
<span class="cline-any cline-no"> </span>
|
|
745
|
-
<span class="cline-any cline-no"> </span>
|
|
746
|
-
<span class="cline-any cline-no"> </span>
|
|
747
|
-
<span class="cline-any cline-no"> </span>
|
|
748
|
-
<span class="cline-any cline-no"> </span>
|
|
749
|
-
<span class="cline-any cline-no"> </span>
|
|
750
|
-
<span class="cline-any cline-no"> </span>
|
|
751
|
-
<span class="cline-any cline-no"> </span>
|
|
752
|
-
<span class="cline-any cline-no"> </span>
|
|
753
|
-
<span class="cline-any cline-no"> </span>
|
|
754
|
-
<span class="cline-any cline-no"> </span>
|
|
755
|
-
<span class="cline-any cline-no"> </span>
|
|
756
|
-
<span class="cline-any cline-no"> </span>
|
|
757
|
-
<span class="cline-any cline-no"> </span>
|
|
758
|
-
<span class="cline-any cline-no"> </span>
|
|
759
|
-
<span class="cline-any cline-no"> </span>
|
|
760
|
-
<span class="cline-any cline-no"> </span>
|
|
761
|
-
<span class="cline-any cline-no"> </span>
|
|
762
|
-
<span class="cline-any cline-no"> </span>
|
|
763
|
-
<span class="cline-any cline-no"> </span>
|
|
764
|
-
<span class="cline-any cline-no"> </span>
|
|
765
|
-
<span class="cline-any cline-no"> </span>
|
|
766
|
-
<span class="cline-any cline-no"> </span>
|
|
767
|
-
<span class="cline-any cline-no"> </span>
|
|
768
|
-
<span class="cline-any cline-no"> </span>
|
|
769
|
-
<span class="cline-any cline-no"> </span>
|
|
770
|
-
<span class="cline-any cline-no"> </span>
|
|
771
|
-
<span class="cline-any cline-no"> </span>
|
|
772
|
-
<span class="cline-any cline-no"> </span>
|
|
773
|
-
<span class="cline-any cline-no"> </span>
|
|
774
|
-
<span class="cline-any cline-no"> </span>
|
|
775
|
-
<span class="cline-any cline-no"> </span>
|
|
776
|
-
<span class="cline-any cline-no"> </span>
|
|
777
|
-
<span class="cline-any cline-no"> </span>
|
|
778
|
-
<span class="cline-any cline-no"> </span>
|
|
779
|
-
<span class="cline-any cline-no"> </span>
|
|
780
|
-
<span class="cline-any cline-no"> </span>
|
|
781
|
-
<span class="cline-any cline-no"> </span>
|
|
782
|
-
<span class="cline-any cline-no"> </span>
|
|
783
|
-
<span class="cline-any cline-no"> </span>
|
|
784
|
-
<span class="cline-any cline-no"> </span>
|
|
785
|
-
<span class="cline-any cline-no"> </span>
|
|
786
|
-
<span class="cline-any cline-no"> </span>
|
|
787
|
-
<span class="cline-any cline-no"> </span>
|
|
788
|
-
<span class="cline-any cline-no"> </span>
|
|
789
|
-
<span class="cline-any cline-no"> </span>
|
|
790
|
-
<span class="cline-any cline-no"> </span>
|
|
791
|
-
<span class="cline-any cline-no"> </span>
|
|
792
|
-
<span class="cline-any cline-no"> </span>
|
|
793
|
-
<span class="cline-any cline-no"> </span>
|
|
794
|
-
<span class="cline-any cline-no"> </span>
|
|
795
|
-
<span class="cline-any cline-no"> </span>
|
|
796
|
-
<span class="cline-any cline-no"> </span>
|
|
797
|
-
<span class="cline-any cline-no"> </span>
|
|
798
|
-
<span class="cline-any cline-no"> </span>
|
|
799
|
-
<span class="cline-any cline-no"> </span>
|
|
800
|
-
<span class="cline-any cline-no"> </span>
|
|
801
|
-
<span class="cline-any cline-no"> </span>
|
|
802
|
-
<span class="cline-any cline-no"> </span>
|
|
803
|
-
<span class="cline-any cline-no"> </span>
|
|
804
|
-
<span class="cline-any cline-no"> </span>
|
|
805
|
-
<span class="cline-any cline-no"> </span>
|
|
806
|
-
<span class="cline-any cline-no"> </span>
|
|
807
|
-
<span class="cline-any cline-no"> </span>
|
|
808
|
-
<span class="cline-any cline-no"> </span>
|
|
809
|
-
<span class="cline-any cline-no"> </span>
|
|
810
|
-
<span class="cline-any cline-no"> </span>
|
|
811
|
-
<span class="cline-any cline-no"> </span>
|
|
812
|
-
<span class="cline-any cline-no"> </span>
|
|
813
|
-
<span class="cline-any cline-no"> </span>
|
|
814
|
-
<span class="cline-any cline-no"> </span>
|
|
815
|
-
<span class="cline-any cline-no"> </span>
|
|
816
|
-
<span class="cline-any cline-no"> </span>
|
|
817
|
-
<span class="cline-any cline-no"> </span>
|
|
818
|
-
<span class="cline-any cline-no"> </span>
|
|
819
|
-
<span class="cline-any cline-no"> </span>
|
|
820
|
-
<span class="cline-any cline-no"> </span>
|
|
821
|
-
<span class="cline-any cline-no"> </span>
|
|
822
|
-
<span class="cline-any cline-no"> </span>
|
|
823
|
-
<span class="cline-any cline-no"> </span>
|
|
824
|
-
<span class="cline-any cline-no"> </span>
|
|
825
|
-
<span class="cline-any cline-no"> </span>
|
|
826
|
-
<span class="cline-any cline-no"> </span>
|
|
827
|
-
<span class="cline-any cline-no"> </span>
|
|
828
|
-
<span class="cline-any cline-no"> </span>
|
|
829
|
-
<span class="cline-any cline-no"> </span>
|
|
830
|
-
<span class="cline-any cline-no"> </span>
|
|
831
|
-
<span class="cline-any cline-no"> </span>
|
|
832
|
-
<span class="cline-any cline-no"> </span>
|
|
833
|
-
<span class="cline-any cline-no"> </span>
|
|
834
|
-
<span class="cline-any cline-no"> </span>
|
|
835
|
-
<span class="cline-any cline-no"> </span>
|
|
836
|
-
<span class="cline-any cline-no"> </span>
|
|
837
|
-
<span class="cline-any cline-no"> </span>
|
|
838
|
-
<span class="cline-any cline-no"> </span>
|
|
839
|
-
<span class="cline-any cline-no"> </span>
|
|
840
|
-
<span class="cline-any cline-no"> </span>
|
|
841
|
-
<span class="cline-any cline-no"> </span>
|
|
842
|
-
<span class="cline-any cline-no"> </span>
|
|
843
|
-
<span class="cline-any cline-no"> </span>
|
|
844
|
-
<span class="cline-any cline-no"> </span>
|
|
845
|
-
<span class="cline-any cline-no"> </span>
|
|
846
|
-
<span class="cline-any cline-no"> </span>
|
|
847
|
-
<span class="cline-any cline-no"> </span>
|
|
848
|
-
<span class="cline-any cline-no"> </span>
|
|
849
|
-
<span class="cline-any cline-no"> </span>
|
|
850
|
-
<span class="cline-any cline-no"> </span>
|
|
851
|
-
<span class="cline-any cline-no"> </span>
|
|
852
|
-
<span class="cline-any cline-no"> </span>
|
|
853
|
-
<span class="cline-any cline-no"> </span>
|
|
854
|
-
<span class="cline-any cline-no"> </span>
|
|
855
|
-
<span class="cline-any cline-no"> </span>
|
|
856
|
-
<span class="cline-any cline-no"> </span>
|
|
857
|
-
<span class="cline-any cline-no"> </span>
|
|
858
|
-
<span class="cline-any cline-no"> </span>
|
|
859
|
-
<span class="cline-any cline-no"> </span>
|
|
860
|
-
<span class="cline-any cline-no"> </span>
|
|
861
|
-
<span class="cline-any cline-no"> </span>
|
|
862
|
-
<span class="cline-any cline-no"> </span>
|
|
863
|
-
<span class="cline-any cline-no"> </span>
|
|
864
|
-
<span class="cline-any cline-no"> </span>
|
|
865
|
-
<span class="cline-any cline-no"> </span>
|
|
866
|
-
<span class="cline-any cline-no"> </span>
|
|
867
|
-
<span class="cline-any cline-no"> </span>
|
|
868
|
-
<span class="cline-any cline-no"> </span>
|
|
869
|
-
<span class="cline-any cline-no"> </span>
|
|
870
|
-
<span class="cline-any cline-no"> </span>
|
|
871
|
-
<span class="cline-any cline-no"> </span>
|
|
872
|
-
<span class="cline-any cline-no"> </span>
|
|
873
|
-
<span class="cline-any cline-no"> </span>
|
|
874
|
-
<span class="cline-any cline-no"> </span>
|
|
875
|
-
<span class="cline-any cline-no"> </span>
|
|
876
|
-
<span class="cline-any cline-no"> </span>
|
|
877
|
-
<span class="cline-any cline-no"> </span>
|
|
878
|
-
<span class="cline-any cline-no"> </span>
|
|
879
|
-
<span class="cline-any cline-no"> </span>
|
|
880
|
-
<span class="cline-any cline-no"> </span>
|
|
881
|
-
<span class="cline-any cline-no"> </span>
|
|
882
|
-
<span class="cline-any cline-no"> </span>
|
|
883
|
-
<span class="cline-any cline-no"> </span>
|
|
884
|
-
<span class="cline-any cline-no"> </span>
|
|
885
|
-
<span class="cline-any cline-no"> </span>
|
|
886
|
-
<span class="cline-any cline-no"> </span>
|
|
887
|
-
<span class="cline-any cline-no"> </span>
|
|
888
|
-
<span class="cline-any cline-no"> </span>
|
|
889
|
-
<span class="cline-any cline-no"> </span>
|
|
890
|
-
<span class="cline-any cline-no"> </span>
|
|
891
|
-
<span class="cline-any cline-no"> </span>
|
|
892
|
-
<span class="cline-any cline-no"> </span>
|
|
893
|
-
<span class="cline-any cline-no"> </span>
|
|
894
|
-
<span class="cline-any cline-no"> </span>
|
|
895
|
-
<span class="cline-any cline-no"> </span>
|
|
896
|
-
<span class="cline-any cline-no"> </span>
|
|
897
|
-
<span class="cline-any cline-no"> </span>
|
|
898
|
-
<span class="cline-any cline-no"> </span>
|
|
899
|
-
<span class="cline-any cline-no"> </span>
|
|
900
|
-
<span class="cline-any cline-no"> </span>
|
|
901
|
-
<span class="cline-any cline-no"> </span>
|
|
902
|
-
<span class="cline-any cline-no"> </span>
|
|
903
|
-
<span class="cline-any cline-no"> </span>
|
|
904
|
-
<span class="cline-any cline-no"> </span>
|
|
905
|
-
<span class="cline-any cline-no"> </span>
|
|
906
|
-
<span class="cline-any cline-no"> </span>
|
|
907
|
-
<span class="cline-any cline-no"> </span>
|
|
908
|
-
<span class="cline-any cline-no"> </span>
|
|
909
|
-
<span class="cline-any cline-no"> </span>
|
|
910
|
-
<span class="cline-any cline-no"> </span>
|
|
911
|
-
<span class="cline-any cline-no"> </span>
|
|
912
|
-
<span class="cline-any cline-no"> </span>
|
|
913
|
-
<span class="cline-any cline-no"> </span>
|
|
914
|
-
<span class="cline-any cline-no"> </span>
|
|
915
|
-
<span class="cline-any cline-no"> </span>
|
|
916
|
-
<span class="cline-any cline-no"> </span>
|
|
917
|
-
<span class="cline-any cline-no"> </span>
|
|
918
|
-
<span class="cline-any cline-no"> </span>
|
|
919
|
-
<span class="cline-any cline-no"> </span>
|
|
920
|
-
<span class="cline-any cline-no"> </span>
|
|
921
|
-
<span class="cline-any cline-no"> </span>
|
|
922
|
-
<span class="cline-any cline-no"> </span>
|
|
923
|
-
<span class="cline-any cline-no"> </span>
|
|
924
|
-
<span class="cline-any cline-no"> </span>
|
|
925
|
-
<span class="cline-any cline-no"> </span>
|
|
926
|
-
<span class="cline-any cline-no"> </span>
|
|
927
|
-
<span class="cline-any cline-no"> </span>
|
|
928
|
-
<span class="cline-any cline-no"> </span>
|
|
929
|
-
<span class="cline-any cline-no"> </span>
|
|
930
|
-
<span class="cline-any cline-no"> </span>
|
|
931
|
-
<span class="cline-any cline-no"> </span>
|
|
932
|
-
<span class="cline-any cline-no"> </span>
|
|
933
|
-
<span class="cline-any cline-no"> </span>
|
|
934
|
-
<span class="cline-any cline-no"> </span>
|
|
935
|
-
<span class="cline-any cline-no"> </span>
|
|
936
|
-
<span class="cline-any cline-no"> </span>
|
|
937
|
-
<span class="cline-any cline-no"> </span>
|
|
938
|
-
<span class="cline-any cline-no"> </span>
|
|
939
|
-
<span class="cline-any cline-no"> </span>
|
|
940
|
-
<span class="cline-any cline-no"> </span>
|
|
941
|
-
<span class="cline-any cline-no"> </span>
|
|
942
|
-
<span class="cline-any cline-no"> </span>
|
|
943
|
-
<span class="cline-any cline-no"> </span>
|
|
944
|
-
<span class="cline-any cline-no"> </span>
|
|
945
|
-
<span class="cline-any cline-no"> </span>
|
|
946
|
-
<span class="cline-any cline-no"> </span>
|
|
947
|
-
<span class="cline-any cline-no"> </span>
|
|
948
|
-
<span class="cline-any cline-no"> </span>
|
|
949
|
-
<span class="cline-any cline-no"> </span>
|
|
950
|
-
<span class="cline-any cline-no"> </span>
|
|
951
|
-
<span class="cline-any cline-no"> </span>
|
|
952
|
-
<span class="cline-any cline-no"> </span>
|
|
953
|
-
<span class="cline-any cline-no"> </span>
|
|
954
|
-
<span class="cline-any cline-no"> </span>
|
|
955
|
-
<span class="cline-any cline-no"> </span>
|
|
956
|
-
<span class="cline-any cline-no"> </span>
|
|
957
|
-
<span class="cline-any cline-no"> </span>
|
|
958
|
-
<span class="cline-any cline-no"> </span>
|
|
959
|
-
<span class="cline-any cline-no"> </span>
|
|
960
|
-
<span class="cline-any cline-no"> </span>
|
|
961
|
-
<span class="cline-any cline-no"> </span>
|
|
962
|
-
<span class="cline-any cline-no"> </span>
|
|
963
|
-
<span class="cline-any cline-no"> </span>
|
|
964
|
-
<span class="cline-any cline-no"> </span>
|
|
965
|
-
<span class="cline-any cline-no"> </span>
|
|
966
|
-
<span class="cline-any cline-no"> </span>
|
|
967
|
-
<span class="cline-any cline-no"> </span>
|
|
968
|
-
<span class="cline-any cline-no"> </span>
|
|
969
|
-
<span class="cline-any cline-no"> </span>
|
|
970
|
-
<span class="cline-any cline-no"> </span>
|
|
971
|
-
<span class="cline-any cline-no"> </span>
|
|
972
|
-
<span class="cline-any cline-no"> </span>
|
|
973
|
-
<span class="cline-any cline-no"> </span>
|
|
974
|
-
<span class="cline-any cline-no"> </span>
|
|
975
|
-
<span class="cline-any cline-no"> </span>
|
|
976
|
-
<span class="cline-any cline-no"> </span>
|
|
977
|
-
<span class="cline-any cline-no"> </span>
|
|
978
|
-
<span class="cline-any cline-no"> </span>
|
|
979
|
-
<span class="cline-any cline-no"> </span>
|
|
980
|
-
<span class="cline-any cline-no"> </span>
|
|
981
|
-
<span class="cline-any cline-no"> </span>
|
|
982
|
-
<span class="cline-any cline-no"> </span>
|
|
983
|
-
<span class="cline-any cline-no"> </span>
|
|
984
|
-
<span class="cline-any cline-no"> </span>
|
|
985
|
-
<span class="cline-any cline-no"> </span>
|
|
986
|
-
<span class="cline-any cline-no"> </span>
|
|
987
|
-
<span class="cline-any cline-no"> </span>
|
|
988
|
-
<span class="cline-any cline-no"> </span>
|
|
989
|
-
<span class="cline-any cline-no"> </span>
|
|
990
|
-
<span class="cline-any cline-no"> </span>
|
|
991
|
-
<span class="cline-any cline-no"> </span>
|
|
992
|
-
<span class="cline-any cline-no"> </span>
|
|
993
|
-
<span class="cline-any cline-no"> </span>
|
|
994
|
-
<span class="cline-any cline-no"> </span>
|
|
995
|
-
<span class="cline-any cline-no"> </span>
|
|
996
|
-
<span class="cline-any cline-no"> </span>
|
|
997
|
-
<span class="cline-any cline-no"> </span>
|
|
998
|
-
<span class="cline-any cline-no"> </span>
|
|
999
|
-
<span class="cline-any cline-no"> </span>
|
|
1000
|
-
<span class="cline-any cline-no"> </span>
|
|
1001
|
-
<span class="cline-any cline-no"> </span>
|
|
1002
|
-
<span class="cline-any cline-no"> </span>
|
|
1003
|
-
<span class="cline-any cline-no"> </span>
|
|
1004
|
-
<span class="cline-any cline-no"> </span>
|
|
1005
|
-
<span class="cline-any cline-no"> </span>
|
|
1006
|
-
<span class="cline-any cline-no"> </span>
|
|
1007
|
-
<span class="cline-any cline-no"> </span>
|
|
1008
|
-
<span class="cline-any cline-no"> </span>
|
|
1009
|
-
<span class="cline-any cline-no"> </span>
|
|
1010
|
-
<span class="cline-any cline-no"> </span>
|
|
1011
|
-
<span class="cline-any cline-no"> </span>
|
|
1012
|
-
<span class="cline-any cline-no"> </span>
|
|
1013
|
-
<span class="cline-any cline-no"> </span>
|
|
1014
|
-
<span class="cline-any cline-no"> </span>
|
|
1015
|
-
<span class="cline-any cline-no"> </span>
|
|
1016
|
-
<span class="cline-any cline-no"> </span>
|
|
1017
|
-
<span class="cline-any cline-no"> </span>
|
|
1018
|
-
<span class="cline-any cline-no"> </span>
|
|
1019
|
-
<span class="cline-any cline-no"> </span>
|
|
1020
|
-
<span class="cline-any cline-no"> </span>
|
|
1021
|
-
<span class="cline-any cline-no"> </span>
|
|
1022
|
-
<span class="cline-any cline-no"> </span>
|
|
1023
|
-
<span class="cline-any cline-no"> </span>
|
|
1024
|
-
<span class="cline-any cline-no"> </span>
|
|
1025
|
-
<span class="cline-any cline-no"> </span>
|
|
1026
|
-
<span class="cline-any cline-no"> </span>
|
|
1027
|
-
<span class="cline-any cline-no"> </span>
|
|
1028
|
-
<span class="cline-any cline-no"> </span>
|
|
1029
|
-
<span class="cline-any cline-no"> </span>
|
|
1030
|
-
<span class="cline-any cline-no"> </span>
|
|
1031
|
-
<span class="cline-any cline-no"> </span>
|
|
1032
|
-
<span class="cline-any cline-no"> </span>
|
|
1033
|
-
<span class="cline-any cline-no"> </span>
|
|
1034
|
-
<span class="cline-any cline-no"> </span>
|
|
1035
|
-
<span class="cline-any cline-no"> </span>
|
|
1036
|
-
<span class="cline-any cline-no"> </span>
|
|
1037
|
-
<span class="cline-any cline-no"> </span>
|
|
1038
|
-
<span class="cline-any cline-no"> </span>
|
|
1039
|
-
<span class="cline-any cline-no"> </span>
|
|
1040
|
-
<span class="cline-any cline-no"> </span>
|
|
1041
|
-
<span class="cline-any cline-no"> </span>
|
|
1042
|
-
<span class="cline-any cline-no"> </span>
|
|
1043
|
-
<span class="cline-any cline-no"> </span>
|
|
1044
|
-
<span class="cline-any cline-no"> </span>
|
|
1045
|
-
<span class="cline-any cline-no"> </span>
|
|
1046
|
-
<span class="cline-any cline-no"> </span>
|
|
1047
|
-
<span class="cline-any cline-no"> </span>
|
|
1048
|
-
<span class="cline-any cline-no"> </span>
|
|
1049
|
-
<span class="cline-any cline-no"> </span>
|
|
1050
|
-
<span class="cline-any cline-no"> </span>
|
|
1051
|
-
<span class="cline-any cline-no"> </span>
|
|
1052
|
-
<span class="cline-any cline-no"> </span>
|
|
1053
|
-
<span class="cline-any cline-no"> </span>
|
|
1054
|
-
<span class="cline-any cline-no"> </span>
|
|
1055
|
-
<span class="cline-any cline-no"> </span>
|
|
1056
|
-
<span class="cline-any cline-no"> </span>
|
|
1057
|
-
<span class="cline-any cline-no"> </span>
|
|
1058
|
-
<span class="cline-any cline-no"> </span>
|
|
1059
|
-
<span class="cline-any cline-no"> </span>
|
|
1060
|
-
<span class="cline-any cline-no"> </span>
|
|
1061
|
-
<span class="cline-any cline-no"> </span>
|
|
1062
|
-
<span class="cline-any cline-no"> </span>
|
|
1063
|
-
<span class="cline-any cline-no"> </span>
|
|
1064
|
-
<span class="cline-any cline-no"> </span>
|
|
1065
|
-
<span class="cline-any cline-no"> </span>
|
|
1066
|
-
<span class="cline-any cline-no"> </span>
|
|
1067
|
-
<span class="cline-any cline-no"> </span>
|
|
1068
|
-
<span class="cline-any cline-no"> </span>
|
|
1069
|
-
<span class="cline-any cline-no"> </span>
|
|
1070
|
-
<span class="cline-any cline-no"> </span>
|
|
1071
|
-
<span class="cline-any cline-no"> </span>
|
|
1072
|
-
<span class="cline-any cline-no"> </span>
|
|
1073
|
-
<span class="cline-any cline-no"> </span>
|
|
1074
|
-
<span class="cline-any cline-no"> </span>
|
|
1075
|
-
<span class="cline-any cline-no"> </span>
|
|
1076
|
-
<span class="cline-any cline-no"> </span>
|
|
1077
|
-
<span class="cline-any cline-no"> </span>
|
|
1078
|
-
<span class="cline-any cline-no"> </span>
|
|
1079
|
-
<span class="cline-any cline-no"> </span>
|
|
1080
|
-
<span class="cline-any cline-no"> </span>
|
|
1081
|
-
<span class="cline-any cline-no"> </span>
|
|
1082
|
-
<span class="cline-any cline-no"> </span>
|
|
1083
|
-
<span class="cline-any cline-no"> </span>
|
|
1084
|
-
<span class="cline-any cline-no"> </span>
|
|
1085
|
-
<span class="cline-any cline-no"> </span>
|
|
1086
|
-
<span class="cline-any cline-no"> </span>
|
|
1087
|
-
<span class="cline-any cline-no"> </span>
|
|
1088
|
-
<span class="cline-any cline-no"> </span>
|
|
1089
|
-
<span class="cline-any cline-no"> </span>
|
|
1090
|
-
<span class="cline-any cline-no"> </span>
|
|
1091
|
-
<span class="cline-any cline-no"> </span>
|
|
1092
|
-
<span class="cline-any cline-no"> </span>
|
|
1093
|
-
<span class="cline-any cline-no"> </span>
|
|
1094
|
-
<span class="cline-any cline-no"> </span>
|
|
1095
|
-
<span class="cline-any cline-no"> </span>
|
|
1096
|
-
<span class="cline-any cline-no"> </span>
|
|
1097
|
-
<span class="cline-any cline-no"> </span>
|
|
1098
|
-
<span class="cline-any cline-no"> </span>
|
|
1099
|
-
<span class="cline-any cline-no"> </span>
|
|
1100
|
-
<span class="cline-any cline-no"> </span>
|
|
1101
|
-
<span class="cline-any cline-no"> </span>
|
|
1102
|
-
<span class="cline-any cline-no"> </span>
|
|
1103
|
-
<span class="cline-any cline-no"> </span>
|
|
1104
|
-
<span class="cline-any cline-no"> </span>
|
|
1105
|
-
<span class="cline-any cline-no"> </span>
|
|
1106
|
-
<span class="cline-any cline-no"> </span>
|
|
1107
|
-
<span class="cline-any cline-no"> </span>
|
|
1108
|
-
<span class="cline-any cline-no"> </span>
|
|
1109
|
-
<span class="cline-any cline-no"> </span>
|
|
1110
|
-
<span class="cline-any cline-no"> </span>
|
|
1111
|
-
<span class="cline-any cline-no"> </span>
|
|
1112
|
-
<span class="cline-any cline-no"> </span>
|
|
1113
|
-
<span class="cline-any cline-no"> </span>
|
|
1114
|
-
<span class="cline-any cline-no"> </span>
|
|
1115
|
-
<span class="cline-any cline-no"> </span>
|
|
1116
|
-
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" >/**<span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span></span>
|
|
1117
|
-
<span class="cstat-no" title="statement not covered" > * Path Validator - HIGH-2 Remediation</span>
|
|
1118
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1119
|
-
<span class="cstat-no" title="statement not covered" > * Fixes path traversal vulnerabilities by:</span>
|
|
1120
|
-
<span class="cstat-no" title="statement not covered" > * - Validating all file paths against allowed prefixes</span>
|
|
1121
|
-
<span class="cstat-no" title="statement not covered" > * - Using path.resolve() for canonicalization</span>
|
|
1122
|
-
<span class="cstat-no" title="statement not covered" > * - Blocking traversal patterns (../, etc.)</span>
|
|
1123
|
-
<span class="cstat-no" title="statement not covered" > * - Enforcing path length limits</span>
|
|
1124
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1125
|
-
<span class="cstat-no" title="statement not covered" > * Security Properties:</span>
|
|
1126
|
-
<span class="cstat-no" title="statement not covered" > * - Path canonicalization</span>
|
|
1127
|
-
<span class="cstat-no" title="statement not covered" > * - Prefix validation</span>
|
|
1128
|
-
<span class="cstat-no" title="statement not covered" > * - Symlink resolution (optional)</span>
|
|
1129
|
-
<span class="cstat-no" title="statement not covered" > * - Traversal pattern detection</span>
|
|
1130
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1131
|
-
<span class="cstat-no" title="statement not covered" > * @module v3/security/path-validator</span>
|
|
1132
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1133
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1134
|
-
<span class="cstat-no" title="statement not covered" >import * as path from 'path';</span>
|
|
1135
|
-
<span class="cstat-no" title="statement not covered" >import * as fs from 'fs/promises';</span>
|
|
1136
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1137
|
-
<span class="cstat-no" title="statement not covered" >export interface PathValidatorConfig {</span>
|
|
1138
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1139
|
-
<span class="cstat-no" title="statement not covered" > * Allowed directory prefixes.</span>
|
|
1140
|
-
<span class="cstat-no" title="statement not covered" > * Paths must start with one of these after resolution.</span>
|
|
1141
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1142
|
-
<span class="cstat-no" title="statement not covered" > allowedPrefixes: string[];</span>
|
|
1143
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1144
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1145
|
-
<span class="cstat-no" title="statement not covered" > * Blocked file extensions.</span>
|
|
1146
|
-
<span class="cstat-no" title="statement not covered" > * Files with these extensions are rejected.</span>
|
|
1147
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1148
|
-
<span class="cstat-no" title="statement not covered" > blockedExtensions?: string[];</span>
|
|
1149
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1150
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1151
|
-
<span class="cstat-no" title="statement not covered" > * Blocked file names.</span>
|
|
1152
|
-
<span class="cstat-no" title="statement not covered" > * Files matching these names are rejected.</span>
|
|
1153
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1154
|
-
<span class="cstat-no" title="statement not covered" > blockedNames?: string[];</span>
|
|
1155
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1156
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1157
|
-
<span class="cstat-no" title="statement not covered" > * Maximum path length.</span>
|
|
1158
|
-
<span class="cstat-no" title="statement not covered" > * Default: 4096 characters</span>
|
|
1159
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1160
|
-
<span class="cstat-no" title="statement not covered" > maxPathLength?: number;</span>
|
|
1161
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1162
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1163
|
-
<span class="cstat-no" title="statement not covered" > * Whether to resolve symlinks.</span>
|
|
1164
|
-
<span class="cstat-no" title="statement not covered" > * Default: true</span>
|
|
1165
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1166
|
-
<span class="cstat-no" title="statement not covered" > resolveSymlinks?: boolean;</span>
|
|
1167
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1168
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1169
|
-
<span class="cstat-no" title="statement not covered" > * Whether to allow paths that don't exist.</span>
|
|
1170
|
-
<span class="cstat-no" title="statement not covered" > * Default: true (for write operations)</span>
|
|
1171
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1172
|
-
<span class="cstat-no" title="statement not covered" > allowNonExistent?: boolean;</span>
|
|
1173
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1174
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1175
|
-
<span class="cstat-no" title="statement not covered" > * Whether to allow hidden files/directories.</span>
|
|
1176
|
-
<span class="cstat-no" title="statement not covered" > * Default: false</span>
|
|
1177
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1178
|
-
<span class="cstat-no" title="statement not covered" > allowHidden?: boolean;</span>
|
|
1179
|
-
<span class="cstat-no" title="statement not covered" >}</span>
|
|
1180
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1181
|
-
<span class="cstat-no" title="statement not covered" >export interface PathValidationResult {</span>
|
|
1182
|
-
<span class="cstat-no" title="statement not covered" > isValid: boolean;</span>
|
|
1183
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: string;</span>
|
|
1184
|
-
<span class="cstat-no" title="statement not covered" > relativePath: string;</span>
|
|
1185
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: string;</span>
|
|
1186
|
-
<span class="cstat-no" title="statement not covered" > errors: string[];</span>
|
|
1187
|
-
<span class="cstat-no" title="statement not covered" >}</span>
|
|
1188
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1189
|
-
<span class="cstat-no" title="statement not covered" >export class PathValidatorError extends Error {</span>
|
|
1190
|
-
<span class="cstat-no" title="statement not covered" > constructor(</span>
|
|
1191
|
-
<span class="cstat-no" title="statement not covered" > message: string,</span>
|
|
1192
|
-
<span class="cstat-no" title="statement not covered" > public readonly code: string,</span>
|
|
1193
|
-
<span class="cstat-no" title="statement not covered" > public readonly path?: string,</span>
|
|
1194
|
-
<span class="cstat-no" title="statement not covered" > ) {</span>
|
|
1195
|
-
<span class="cstat-no" title="statement not covered" > super(message);</span>
|
|
1196
|
-
<span class="cstat-no" title="statement not covered" > this.name = 'PathValidatorError';</span>
|
|
1197
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1198
|
-
<span class="cstat-no" title="statement not covered" >}</span>
|
|
1199
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1200
|
-
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
1201
|
-
<span class="cstat-no" title="statement not covered" > * Dangerous path patterns that indicate traversal attempts.</span>
|
|
1202
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1203
|
-
<span class="cstat-no" title="statement not covered" >const TRAVERSAL_PATTERNS = [</span>
|
|
1204
|
-
<span class="cstat-no" title="statement not covered" > /\.\.\//, // ../</span>
|
|
1205
|
-
<span class="cstat-no" title="statement not covered" > /\.\.\\/, // ..\</span>
|
|
1206
|
-
<span class="cstat-no" title="statement not covered" > /\.\./, // .. anywhere</span>
|
|
1207
|
-
<span class="cstat-no" title="statement not covered" > /%2e%2e/i, // URL-encoded ..</span>
|
|
1208
|
-
<span class="cstat-no" title="statement not covered" > /%252e%252e/i, // Double URL-encoded ..</span>
|
|
1209
|
-
<span class="cstat-no" title="statement not covered" > /\.%2e/i, // Mixed encoding</span>
|
|
1210
|
-
<span class="cstat-no" title="statement not covered" > /%2e\./i, // Mixed encoding</span>
|
|
1211
|
-
<span class="cstat-no" title="statement not covered" > /\0/, // Null byte</span>
|
|
1212
|
-
<span class="cstat-no" title="statement not covered" > /%00/, // URL-encoded null</span>
|
|
1213
|
-
<span class="cstat-no" title="statement not covered" >];</span>
|
|
1214
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1215
|
-
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
1216
|
-
<span class="cstat-no" title="statement not covered" > * Default blocked file extensions (sensitive files).</span>
|
|
1217
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1218
|
-
<span class="cstat-no" title="statement not covered" >const DEFAULT_BLOCKED_EXTENSIONS = [</span>
|
|
1219
|
-
<span class="cstat-no" title="statement not covered" > '.env',</span>
|
|
1220
|
-
<span class="cstat-no" title="statement not covered" > '.pem',</span>
|
|
1221
|
-
<span class="cstat-no" title="statement not covered" > '.key',</span>
|
|
1222
|
-
<span class="cstat-no" title="statement not covered" > '.crt',</span>
|
|
1223
|
-
<span class="cstat-no" title="statement not covered" > '.pfx',</span>
|
|
1224
|
-
<span class="cstat-no" title="statement not covered" > '.p12',</span>
|
|
1225
|
-
<span class="cstat-no" title="statement not covered" > '.jks',</span>
|
|
1226
|
-
<span class="cstat-no" title="statement not covered" > '.keystore',</span>
|
|
1227
|
-
<span class="cstat-no" title="statement not covered" > '.secret',</span>
|
|
1228
|
-
<span class="cstat-no" title="statement not covered" > '.credentials',</span>
|
|
1229
|
-
<span class="cstat-no" title="statement not covered" >];</span>
|
|
1230
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1231
|
-
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
1232
|
-
<span class="cstat-no" title="statement not covered" > * Default blocked file names (sensitive files).</span>
|
|
1233
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1234
|
-
<span class="cstat-no" title="statement not covered" >const DEFAULT_BLOCKED_NAMES = [</span>
|
|
1235
|
-
<span class="cstat-no" title="statement not covered" > 'id_rsa',</span>
|
|
1236
|
-
<span class="cstat-no" title="statement not covered" > 'id_dsa',</span>
|
|
1237
|
-
<span class="cstat-no" title="statement not covered" > 'id_ecdsa',</span>
|
|
1238
|
-
<span class="cstat-no" title="statement not covered" > 'id_ed25519',</span>
|
|
1239
|
-
<span class="cstat-no" title="statement not covered" > '.htpasswd',</span>
|
|
1240
|
-
<span class="cstat-no" title="statement not covered" > '.htaccess',</span>
|
|
1241
|
-
<span class="cstat-no" title="statement not covered" > 'shadow',</span>
|
|
1242
|
-
<span class="cstat-no" title="statement not covered" > 'passwd',</span>
|
|
1243
|
-
<span class="cstat-no" title="statement not covered" > 'authorized_keys',</span>
|
|
1244
|
-
<span class="cstat-no" title="statement not covered" > 'known_hosts',</span>
|
|
1245
|
-
<span class="cstat-no" title="statement not covered" > '.git',</span>
|
|
1246
|
-
<span class="cstat-no" title="statement not covered" > '.gitconfig',</span>
|
|
1247
|
-
<span class="cstat-no" title="statement not covered" > '.npmrc',</span>
|
|
1248
|
-
<span class="cstat-no" title="statement not covered" > '.docker',</span>
|
|
1249
|
-
<span class="cstat-no" title="statement not covered" >];</span>
|
|
1250
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1251
|
-
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
1252
|
-
<span class="cstat-no" title="statement not covered" > * Path validator that prevents traversal attacks.</span>
|
|
1253
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1254
|
-
<span class="cstat-no" title="statement not covered" > * This class validates file paths to ensure they stay within</span>
|
|
1255
|
-
<span class="cstat-no" title="statement not covered" > * allowed directories and don't access sensitive files.</span>
|
|
1256
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1257
|
-
<span class="cstat-no" title="statement not covered" > * @example</span>
|
|
1258
|
-
<span class="cstat-no" title="statement not covered" > * ```typescript</span>
|
|
1259
|
-
<span class="cstat-no" title="statement not covered" > * const validator = new PathValidator({</span>
|
|
1260
|
-
<span class="cstat-no" title="statement not covered" > * allowedPrefixes: ['/workspaces/project']</span>
|
|
1261
|
-
<span class="cstat-no" title="statement not covered" > * });</span>
|
|
1262
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1263
|
-
<span class="cstat-no" title="statement not covered" > * const result = await validator.validate('/workspaces/project/src/file.ts');</span>
|
|
1264
|
-
<span class="cstat-no" title="statement not covered" > * if (result.isValid) {</span>
|
|
1265
|
-
<span class="cstat-no" title="statement not covered" > * // Safe to use result.resolvedPath</span>
|
|
1266
|
-
<span class="cstat-no" title="statement not covered" > * }</span>
|
|
1267
|
-
<span class="cstat-no" title="statement not covered" > * ```</span>
|
|
1268
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1269
|
-
<span class="cstat-no" title="statement not covered" >export class PathValidator {</span>
|
|
1270
|
-
<span class="cstat-no" title="statement not covered" > private readonly config: Required<PathValidatorConfig>;</span>
|
|
1271
|
-
<span class="cstat-no" title="statement not covered" > private readonly resolvedPrefixes: string[];</span>
|
|
1272
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1273
|
-
<span class="cstat-no" title="statement not covered" > constructor(config: PathValidatorConfig) {</span>
|
|
1274
|
-
<span class="cstat-no" title="statement not covered" > this.config = {</span>
|
|
1275
|
-
<span class="cstat-no" title="statement not covered" > allowedPrefixes: config.allowedPrefixes,</span>
|
|
1276
|
-
<span class="cstat-no" title="statement not covered" > blockedExtensions: config.blockedExtensions ?? DEFAULT_BLOCKED_EXTENSIONS,</span>
|
|
1277
|
-
<span class="cstat-no" title="statement not covered" > blockedNames: config.blockedNames ?? DEFAULT_BLOCKED_NAMES,</span>
|
|
1278
|
-
<span class="cstat-no" title="statement not covered" > maxPathLength: config.maxPathLength ?? 4096,</span>
|
|
1279
|
-
<span class="cstat-no" title="statement not covered" > resolveSymlinks: config.resolveSymlinks ?? true,</span>
|
|
1280
|
-
<span class="cstat-no" title="statement not covered" > allowNonExistent: config.allowNonExistent ?? true,</span>
|
|
1281
|
-
<span class="cstat-no" title="statement not covered" > allowHidden: config.allowHidden ?? false,</span>
|
|
1282
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1283
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1284
|
-
<span class="cstat-no" title="statement not covered" > if (this.config.allowedPrefixes.length === 0) {</span>
|
|
1285
|
-
<span class="cstat-no" title="statement not covered" > throw new PathValidatorError(</span>
|
|
1286
|
-
<span class="cstat-no" title="statement not covered" > 'At least one allowed prefix must be specified',</span>
|
|
1287
|
-
<span class="cstat-no" title="statement not covered" > 'EMPTY_PREFIXES'</span>
|
|
1288
|
-
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1289
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1290
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1291
|
-
<span class="cstat-no" title="statement not covered" > // Pre-resolve all prefixes</span>
|
|
1292
|
-
<span class="cstat-no" title="statement not covered" > this.resolvedPrefixes = this.config.allowedPrefixes.map(p =></span>
|
|
1293
|
-
<span class="cstat-no" title="statement not covered" > path.resolve(p)</span>
|
|
1294
|
-
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1295
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1296
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1297
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1298
|
-
<span class="cstat-no" title="statement not covered" > * Validates a path against security rules.</span>
|
|
1299
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1300
|
-
<span class="cstat-no" title="statement not covered" > * @param inputPath - The path to validate</span>
|
|
1301
|
-
<span class="cstat-no" title="statement not covered" > * @returns Validation result with resolved path</span>
|
|
1302
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1303
|
-
<span class="cstat-no" title="statement not covered" > async validate(inputPath: string): Promise<PathValidationResult> {</span>
|
|
1304
|
-
<span class="cstat-no" title="statement not covered" > const errors: string[] = [];</span>
|
|
1305
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1306
|
-
<span class="cstat-no" title="statement not covered" > // Check for empty path</span>
|
|
1307
|
-
<span class="cstat-no" title="statement not covered" > if (!inputPath || inputPath.trim() === '') {</span>
|
|
1308
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1309
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1310
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: '',</span>
|
|
1311
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1312
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1313
|
-
<span class="cstat-no" title="statement not covered" > errors: ['Path is empty'],</span>
|
|
1314
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1315
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1316
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1317
|
-
<span class="cstat-no" title="statement not covered" > // Check path length</span>
|
|
1318
|
-
<span class="cstat-no" title="statement not covered" > if (inputPath.length > this.config.maxPathLength) {</span>
|
|
1319
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1320
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1321
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: '',</span>
|
|
1322
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1323
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1324
|
-
<span class="cstat-no" title="statement not covered" > errors: [`Path exceeds maximum length of ${this.config.maxPathLength}`],</span>
|
|
1325
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1326
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1327
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1328
|
-
<span class="cstat-no" title="statement not covered" > // Check for traversal patterns</span>
|
|
1329
|
-
<span class="cstat-no" title="statement not covered" > for (const pattern of TRAVERSAL_PATTERNS) {</span>
|
|
1330
|
-
<span class="cstat-no" title="statement not covered" > if (pattern.test(inputPath)) {</span>
|
|
1331
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1332
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1333
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: '',</span>
|
|
1334
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1335
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1336
|
-
<span class="cstat-no" title="statement not covered" > errors: ['Path traversal pattern detected'],</span>
|
|
1337
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1338
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1339
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1340
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1341
|
-
<span class="cstat-no" title="statement not covered" > // Resolve the path</span>
|
|
1342
|
-
<span class="cstat-no" title="statement not covered" > let resolvedPath: string;</span>
|
|
1343
|
-
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1344
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath = path.resolve(inputPath);</span>
|
|
1345
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1346
|
-
<span class="cstat-no" title="statement not covered" > // Optionally resolve symlinks</span>
|
|
1347
|
-
<span class="cstat-no" title="statement not covered" > if (this.config.resolveSymlinks) {</span>
|
|
1348
|
-
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1349
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath = await fs.realpath(resolvedPath);</span>
|
|
1350
|
-
<span class="cstat-no" title="statement not covered" > } catch (error: any) {</span>
|
|
1351
|
-
<span class="cstat-no" title="statement not covered" > // Path doesn't exist yet - use resolved path</span>
|
|
1352
|
-
<span class="cstat-no" title="statement not covered" > if (error.code !== 'ENOENT' || !this.config.allowNonExistent) {</span>
|
|
1353
|
-
<span class="cstat-no" title="statement not covered" > if (error.code === 'ENOENT') {</span>
|
|
1354
|
-
<span class="cstat-no" title="statement not covered" > errors.push('Path does not exist');</span>
|
|
1355
|
-
<span class="cstat-no" title="statement not covered" > } else {</span>
|
|
1356
|
-
<span class="cstat-no" title="statement not covered" > errors.push(`Failed to resolve path: ${error.message}`);</span>
|
|
1357
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1358
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1359
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1360
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1361
|
-
<span class="cstat-no" title="statement not covered" > } catch (error: any) {</span>
|
|
1362
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1363
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1364
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: '',</span>
|
|
1365
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1366
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1367
|
-
<span class="cstat-no" title="statement not covered" > errors: [`Invalid path: ${error.message}`],</span>
|
|
1368
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1369
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1370
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1371
|
-
<span class="cstat-no" title="statement not covered" > // Check against allowed prefixes</span>
|
|
1372
|
-
<span class="cstat-no" title="statement not covered" > let matchedPrefix = '';</span>
|
|
1373
|
-
<span class="cstat-no" title="statement not covered" > let relativePath = '';</span>
|
|
1374
|
-
<span class="cstat-no" title="statement not covered" > let prefixMatched = false;</span>
|
|
1375
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1376
|
-
<span class="cstat-no" title="statement not covered" > for (const prefix of this.resolvedPrefixes) {</span>
|
|
1377
|
-
<span class="cstat-no" title="statement not covered" > if (resolvedPath === prefix || resolvedPath.startsWith(prefix + path.sep)) {</span>
|
|
1378
|
-
<span class="cstat-no" title="statement not covered" > prefixMatched = true;</span>
|
|
1379
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix = prefix;</span>
|
|
1380
|
-
<span class="cstat-no" title="statement not covered" > relativePath = resolvedPath.slice(prefix.length);</span>
|
|
1381
|
-
<span class="cstat-no" title="statement not covered" > if (relativePath.startsWith(path.sep)) {</span>
|
|
1382
|
-
<span class="cstat-no" title="statement not covered" > relativePath = relativePath.slice(1);</span>
|
|
1383
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1384
|
-
<span class="cstat-no" title="statement not covered" > break;</span>
|
|
1385
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1386
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1387
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1388
|
-
<span class="cstat-no" title="statement not covered" > if (!prefixMatched) {</span>
|
|
1389
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1390
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1391
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath,</span>
|
|
1392
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1393
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1394
|
-
<span class="cstat-no" title="statement not covered" > errors: ['Path is outside allowed directories'],</span>
|
|
1395
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1396
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1397
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1398
|
-
<span class="cstat-no" title="statement not covered" > // Check for hidden files</span>
|
|
1399
|
-
<span class="cstat-no" title="statement not covered" > const pathParts = resolvedPath.split(path.sep);</span>
|
|
1400
|
-
<span class="cstat-no" title="statement not covered" > if (!this.config.allowHidden) {</span>
|
|
1401
|
-
<span class="cstat-no" title="statement not covered" > for (const part of pathParts) {</span>
|
|
1402
|
-
<span class="cstat-no" title="statement not covered" > if (part.startsWith('.') && part !== '.' && part !== '..') {</span>
|
|
1403
|
-
<span class="cstat-no" title="statement not covered" > errors.push('Hidden files/directories are not allowed');</span>
|
|
1404
|
-
<span class="cstat-no" title="statement not covered" > break;</span>
|
|
1405
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1406
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1407
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1408
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1409
|
-
<span class="cstat-no" title="statement not covered" > // Check blocked file names</span>
|
|
1410
|
-
<span class="cstat-no" title="statement not covered" > const basename = path.basename(resolvedPath);</span>
|
|
1411
|
-
<span class="cstat-no" title="statement not covered" > if (this.config.blockedNames.includes(basename)) {</span>
|
|
1412
|
-
<span class="cstat-no" title="statement not covered" > errors.push(`File name "${basename}" is blocked`);</span>
|
|
1413
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1414
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1415
|
-
<span class="cstat-no" title="statement not covered" > // Check blocked extensions</span>
|
|
1416
|
-
<span class="cstat-no" title="statement not covered" > const ext = path.extname(resolvedPath).toLowerCase();</span>
|
|
1417
|
-
<span class="cstat-no" title="statement not covered" > if (this.config.blockedExtensions.includes(ext)) {</span>
|
|
1418
|
-
<span class="cstat-no" title="statement not covered" > errors.push(`File extension "${ext}" is blocked`);</span>
|
|
1419
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1420
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1421
|
-
<span class="cstat-no" title="statement not covered" > // Also check for double extensions (e.g., .tar.gz, .config.json)</span>
|
|
1422
|
-
<span class="cstat-no" title="statement not covered" > const fullname = basename.toLowerCase();</span>
|
|
1423
|
-
<span class="cstat-no" title="statement not covered" > for (const blockedExt of this.config.blockedExtensions) {</span>
|
|
1424
|
-
<span class="cstat-no" title="statement not covered" > if (fullname.endsWith(blockedExt)) {</span>
|
|
1425
|
-
<span class="cstat-no" title="statement not covered" > errors.push(`File extension "${blockedExt}" is blocked`);</span>
|
|
1426
|
-
<span class="cstat-no" title="statement not covered" > break;</span>
|
|
1427
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1428
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1429
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1430
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1431
|
-
<span class="cstat-no" title="statement not covered" > isValid: errors.length === 0,</span>
|
|
1432
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath,</span>
|
|
1433
|
-
<span class="cstat-no" title="statement not covered" > relativePath,</span>
|
|
1434
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix,</span>
|
|
1435
|
-
<span class="cstat-no" title="statement not covered" > errors,</span>
|
|
1436
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1437
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1438
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1439
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1440
|
-
<span class="cstat-no" title="statement not covered" > * Validates and returns resolved path, throwing on failure.</span>
|
|
1441
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1442
|
-
<span class="cstat-no" title="statement not covered" > * @param inputPath - The path to validate</span>
|
|
1443
|
-
<span class="cstat-no" title="statement not covered" > * @returns Resolved path if valid</span>
|
|
1444
|
-
<span class="cstat-no" title="statement not covered" > * @throws PathValidatorError if validation fails</span>
|
|
1445
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1446
|
-
<span class="cstat-no" title="statement not covered" > async validateOrThrow(inputPath: string): Promise<string> {</span>
|
|
1447
|
-
<span class="cstat-no" title="statement not covered" > const result = await this.validate(inputPath);</span>
|
|
1448
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1449
|
-
<span class="cstat-no" title="statement not covered" > if (!result.isValid) {</span>
|
|
1450
|
-
<span class="cstat-no" title="statement not covered" > throw new PathValidatorError(</span>
|
|
1451
|
-
<span class="cstat-no" title="statement not covered" > result.errors.join('; '),</span>
|
|
1452
|
-
<span class="cstat-no" title="statement not covered" > 'VALIDATION_FAILED',</span>
|
|
1453
|
-
<span class="cstat-no" title="statement not covered" > inputPath</span>
|
|
1454
|
-
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1455
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1456
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1457
|
-
<span class="cstat-no" title="statement not covered" > return result.resolvedPath;</span>
|
|
1458
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1459
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1460
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1461
|
-
<span class="cstat-no" title="statement not covered" > * Synchronous validation (without symlink resolution).</span>
|
|
1462
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1463
|
-
<span class="cstat-no" title="statement not covered" > * @param inputPath - The path to validate</span>
|
|
1464
|
-
<span class="cstat-no" title="statement not covered" > * @returns Validation result</span>
|
|
1465
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1466
|
-
<span class="cstat-no" title="statement not covered" > validateSync(inputPath: string): PathValidationResult {</span>
|
|
1467
|
-
<span class="cstat-no" title="statement not covered" > const errors: string[] = [];</span>
|
|
1468
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1469
|
-
<span class="cstat-no" title="statement not covered" > if (!inputPath || inputPath.trim() === '') {</span>
|
|
1470
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1471
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1472
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: '',</span>
|
|
1473
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1474
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1475
|
-
<span class="cstat-no" title="statement not covered" > errors: ['Path is empty'],</span>
|
|
1476
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1477
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1478
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1479
|
-
<span class="cstat-no" title="statement not covered" > if (inputPath.length > this.config.maxPathLength) {</span>
|
|
1480
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1481
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1482
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: '',</span>
|
|
1483
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1484
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1485
|
-
<span class="cstat-no" title="statement not covered" > errors: [`Path exceeds maximum length of ${this.config.maxPathLength}`],</span>
|
|
1486
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1487
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1488
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1489
|
-
<span class="cstat-no" title="statement not covered" > for (const pattern of TRAVERSAL_PATTERNS) {</span>
|
|
1490
|
-
<span class="cstat-no" title="statement not covered" > if (pattern.test(inputPath)) {</span>
|
|
1491
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1492
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1493
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath: '',</span>
|
|
1494
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1495
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1496
|
-
<span class="cstat-no" title="statement not covered" > errors: ['Path traversal pattern detected'],</span>
|
|
1497
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1498
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1499
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1500
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1501
|
-
<span class="cstat-no" title="statement not covered" > const resolvedPath = path.resolve(inputPath);</span>
|
|
1502
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1503
|
-
<span class="cstat-no" title="statement not covered" > let matchedPrefix = '';</span>
|
|
1504
|
-
<span class="cstat-no" title="statement not covered" > let relativePath = '';</span>
|
|
1505
|
-
<span class="cstat-no" title="statement not covered" > let prefixMatched = false;</span>
|
|
1506
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1507
|
-
<span class="cstat-no" title="statement not covered" > for (const prefix of this.resolvedPrefixes) {</span>
|
|
1508
|
-
<span class="cstat-no" title="statement not covered" > if (resolvedPath === prefix || resolvedPath.startsWith(prefix + path.sep)) {</span>
|
|
1509
|
-
<span class="cstat-no" title="statement not covered" > prefixMatched = true;</span>
|
|
1510
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix = prefix;</span>
|
|
1511
|
-
<span class="cstat-no" title="statement not covered" > relativePath = resolvedPath.slice(prefix.length);</span>
|
|
1512
|
-
<span class="cstat-no" title="statement not covered" > if (relativePath.startsWith(path.sep)) {</span>
|
|
1513
|
-
<span class="cstat-no" title="statement not covered" > relativePath = relativePath.slice(1);</span>
|
|
1514
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1515
|
-
<span class="cstat-no" title="statement not covered" > break;</span>
|
|
1516
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1517
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1518
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1519
|
-
<span class="cstat-no" title="statement not covered" > if (!prefixMatched) {</span>
|
|
1520
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1521
|
-
<span class="cstat-no" title="statement not covered" > isValid: false,</span>
|
|
1522
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath,</span>
|
|
1523
|
-
<span class="cstat-no" title="statement not covered" > relativePath: '',</span>
|
|
1524
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix: '',</span>
|
|
1525
|
-
<span class="cstat-no" title="statement not covered" > errors: ['Path is outside allowed directories'],</span>
|
|
1526
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1527
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1528
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1529
|
-
<span class="cstat-no" title="statement not covered" > const pathParts = resolvedPath.split(path.sep);</span>
|
|
1530
|
-
<span class="cstat-no" title="statement not covered" > if (!this.config.allowHidden) {</span>
|
|
1531
|
-
<span class="cstat-no" title="statement not covered" > for (const part of pathParts) {</span>
|
|
1532
|
-
<span class="cstat-no" title="statement not covered" > if (part.startsWith('.') && part !== '.' && part !== '..') {</span>
|
|
1533
|
-
<span class="cstat-no" title="statement not covered" > errors.push('Hidden files/directories are not allowed');</span>
|
|
1534
|
-
<span class="cstat-no" title="statement not covered" > break;</span>
|
|
1535
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1536
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1537
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1538
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1539
|
-
<span class="cstat-no" title="statement not covered" > const basename = path.basename(resolvedPath);</span>
|
|
1540
|
-
<span class="cstat-no" title="statement not covered" > if (this.config.blockedNames.includes(basename)) {</span>
|
|
1541
|
-
<span class="cstat-no" title="statement not covered" > errors.push(`File name "${basename}" is blocked`);</span>
|
|
1542
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1543
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1544
|
-
<span class="cstat-no" title="statement not covered" > const ext = path.extname(resolvedPath).toLowerCase();</span>
|
|
1545
|
-
<span class="cstat-no" title="statement not covered" > if (this.config.blockedExtensions.includes(ext)) {</span>
|
|
1546
|
-
<span class="cstat-no" title="statement not covered" > errors.push(`File extension "${ext}" is blocked`);</span>
|
|
1547
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1548
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1549
|
-
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1550
|
-
<span class="cstat-no" title="statement not covered" > isValid: errors.length === 0,</span>
|
|
1551
|
-
<span class="cstat-no" title="statement not covered" > resolvedPath,</span>
|
|
1552
|
-
<span class="cstat-no" title="statement not covered" > relativePath,</span>
|
|
1553
|
-
<span class="cstat-no" title="statement not covered" > matchedPrefix,</span>
|
|
1554
|
-
<span class="cstat-no" title="statement not covered" > errors,</span>
|
|
1555
|
-
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1556
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1557
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1558
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1559
|
-
<span class="cstat-no" title="statement not covered" > * Securely joins path segments within allowed directories.</span>
|
|
1560
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1561
|
-
<span class="cstat-no" title="statement not covered" > * @param prefix - Base directory (must be in allowedPrefixes)</span>
|
|
1562
|
-
<span class="cstat-no" title="statement not covered" > * @param segments - Path segments to join</span>
|
|
1563
|
-
<span class="cstat-no" title="statement not covered" > * @returns Validated resolved path</span>
|
|
1564
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1565
|
-
<span class="cstat-no" title="statement not covered" > async securePath(prefix: string, ...segments: string[]): Promise<string> {</span>
|
|
1566
|
-
<span class="cstat-no" title="statement not covered" > // Join the segments</span>
|
|
1567
|
-
<span class="cstat-no" title="statement not covered" > const joined = path.join(prefix, ...segments);</span>
|
|
1568
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1569
|
-
<span class="cstat-no" title="statement not covered" > // Validate the result</span>
|
|
1570
|
-
<span class="cstat-no" title="statement not covered" > return this.validateOrThrow(joined);</span>
|
|
1571
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1572
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1573
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1574
|
-
<span class="cstat-no" title="statement not covered" > * Adds a prefix to the allowed list at runtime.</span>
|
|
1575
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1576
|
-
<span class="cstat-no" title="statement not covered" > * @param prefix - Prefix to add</span>
|
|
1577
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1578
|
-
<span class="cstat-no" title="statement not covered" > addPrefix(prefix: string): void {</span>
|
|
1579
|
-
<span class="cstat-no" title="statement not covered" > const resolved = path.resolve(prefix);</span>
|
|
1580
|
-
<span class="cstat-no" title="statement not covered" > if (!this.resolvedPrefixes.includes(resolved)) {</span>
|
|
1581
|
-
<span class="cstat-no" title="statement not covered" > this.config.allowedPrefixes.push(prefix);</span>
|
|
1582
|
-
<span class="cstat-no" title="statement not covered" > this.resolvedPrefixes.push(resolved);</span>
|
|
1583
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1584
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1585
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1586
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1587
|
-
<span class="cstat-no" title="statement not covered" > * Returns the current allowed prefixes.</span>
|
|
1588
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1589
|
-
<span class="cstat-no" title="statement not covered" > getAllowedPrefixes(): readonly string[] {</span>
|
|
1590
|
-
<span class="cstat-no" title="statement not covered" > return [...this.resolvedPrefixes];</span>
|
|
1591
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1592
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1593
|
-
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1594
|
-
<span class="cstat-no" title="statement not covered" > * Checks if a path is within allowed prefixes (quick check).</span>
|
|
1595
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1596
|
-
<span class="cstat-no" title="statement not covered" > isWithinAllowed(inputPath: string): boolean {</span>
|
|
1597
|
-
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1598
|
-
<span class="cstat-no" title="statement not covered" > const resolved = path.resolve(inputPath);</span>
|
|
1599
|
-
<span class="cstat-no" title="statement not covered" > return this.resolvedPrefixes.some(</span>
|
|
1600
|
-
<span class="cstat-no" title="statement not covered" > prefix => resolved === prefix || resolved.startsWith(prefix + path.sep)</span>
|
|
1601
|
-
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1602
|
-
<span class="cstat-no" title="statement not covered" > } catch {</span>
|
|
1603
|
-
<span class="cstat-no" title="statement not covered" > return false;</span>
|
|
1604
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1605
|
-
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1606
|
-
<span class="cstat-no" title="statement not covered" >}</span>
|
|
1607
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1608
|
-
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
1609
|
-
<span class="cstat-no" title="statement not covered" > * Factory function to create a path validator for a project directory.</span>
|
|
1610
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1611
|
-
<span class="cstat-no" title="statement not covered" > * @param projectRoot - Root directory of the project</span>
|
|
1612
|
-
<span class="cstat-no" title="statement not covered" > * @returns Configured PathValidator</span>
|
|
1613
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1614
|
-
<span class="cstat-no" title="statement not covered" >export function createProjectPathValidator(projectRoot: string): PathValidator {</span>
|
|
1615
|
-
<span class="cstat-no" title="statement not covered" > const srcDir = path.join(projectRoot, 'src');</span>
|
|
1616
|
-
<span class="cstat-no" title="statement not covered" > const testDir = path.join(projectRoot, 'tests');</span>
|
|
1617
|
-
<span class="cstat-no" title="statement not covered" > const docsDir = path.join(projectRoot, 'docs');</span>
|
|
1618
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1619
|
-
<span class="cstat-no" title="statement not covered" > return new PathValidator({</span>
|
|
1620
|
-
<span class="cstat-no" title="statement not covered" > allowedPrefixes: [srcDir, testDir, docsDir],</span>
|
|
1621
|
-
<span class="cstat-no" title="statement not covered" > allowHidden: false,</span>
|
|
1622
|
-
<span class="cstat-no" title="statement not covered" > });</span>
|
|
1623
|
-
<span class="cstat-no" title="statement not covered" >}</span>
|
|
1624
|
-
<span class="cstat-no" title="statement not covered" ></span>
|
|
1625
|
-
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
1626
|
-
<span class="cstat-no" title="statement not covered" > * Factory function to create a path validator for the entire project.</span>
|
|
1627
|
-
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1628
|
-
<span class="cstat-no" title="statement not covered" > * @param projectRoot - Root directory of the project</span>
|
|
1629
|
-
<span class="cstat-no" title="statement not covered" > * @returns Configured PathValidator</span>
|
|
1630
|
-
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1631
|
-
<span class="cstat-no" title="statement not covered" >export function createFullProjectPathValidator(projectRoot: string): PathValidator {</span>
|
|
1632
|
-
<span class="cstat-no" title="statement not covered" > return new PathValidator({</span>
|
|
1633
|
-
<span class="cstat-no" title="statement not covered" > allowedPrefixes: [projectRoot],</span>
|
|
1634
|
-
<span class="cstat-no" title="statement not covered" > allowHidden: true, // Allow .gitignore, etc.</span>
|
|
1635
|
-
<span class="cstat-no" title="statement not covered" > blockedNames: [</span>
|
|
1636
|
-
<span class="cstat-no" title="statement not covered" > ...DEFAULT_BLOCKED_NAMES,</span>
|
|
1637
|
-
<span class="cstat-no" title="statement not covered" > 'node_modules', // Block access to node_modules</span>
|
|
1638
|
-
<span class="cstat-no" title="statement not covered" > ],</span>
|
|
1639
|
-
<span class="cstat-no" title="statement not covered" > });</span>
|
|
1640
|
-
<span class="cstat-no" title="statement not covered" >}</span>
|
|
1641
|
-
</pre></td></tr></table></pre>
|
|
1642
|
-
|
|
1643
|
-
<div class='push'></div><!-- for sticky footer -->
|
|
1644
|
-
</div><!-- /wrapper -->
|
|
1645
|
-
<div class='footer quiet pad2 space-top1 center small'>
|
|
1646
|
-
Code coverage generated by
|
|
1647
|
-
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1648
|
-
at 2026-01-06T16:55:48.110Z
|
|
1649
|
-
</div>
|
|
1650
|
-
<script src="../prettify.js"></script>
|
|
1651
|
-
<script>
|
|
1652
|
-
window.onload = function () {
|
|
1653
|
-
prettyPrint();
|
|
1654
|
-
};
|
|
1655
|
-
</script>
|
|
1656
|
-
<script src="../sorter.js"></script>
|
|
1657
|
-
<script src="../block-navigation.js"></script>
|
|
1658
|
-
</body>
|
|
1659
|
-
</html>
|
|
1660
|
-
|