|
15 | 15 | // escapeAssertion escapes the dots in the assertion,
|
16 | 16 | // because the expression evaluation doesn't support such variable names.
|
17 | 17 |
|
18 |
| -import parse from 'csv-parse/lib/sync'; |
19 | 18 | import { RoleManager } from '../rbac';
|
20 | 19 |
|
21 | 20 | function escapeAssertion(s: string): string {
|
@@ -157,11 +156,66 @@ function policyArrayToString(policy: string[]): string {
|
157 | 156 | }
|
158 | 157 |
|
159 | 158 | function policyStringToArray(policy: string): string[][] {
|
160 |
| - return parse(policy, { |
161 |
| - delimiter: ',', |
162 |
| - skip_empty_lines: true, |
163 |
| - trim: true, |
164 |
| - }); |
| 159 | + const endCommaRe = /,$/; |
| 160 | + const quotaWrapperRe = /^".*"$/; |
| 161 | + |
| 162 | + const lines: string[] = policy.split(/\r?\n/); |
| 163 | + const arrays: string[][] = []; |
| 164 | + |
| 165 | + for (let line of lines) { |
| 166 | + const commentLabel = line.indexOf('#'); |
| 167 | + if (commentLabel !== -1) { |
| 168 | + line = line.substr(0, commentLabel); |
| 169 | + } |
| 170 | + |
| 171 | + line = line.trim(); |
| 172 | + |
| 173 | + if (endCommaRe.test(line)) { |
| 174 | + throw new Error('The csv standard does not allow a comma at the end of a sentence'); |
| 175 | + } |
| 176 | + |
| 177 | + const slices = line.split(','); |
| 178 | + let tokens: string[] = []; |
| 179 | + |
| 180 | + for (let slice of slices) { |
| 181 | + slice = slice.trim(); |
| 182 | + |
| 183 | + // Remove parcel quotes |
| 184 | + if (quotaWrapperRe.test(slice)) { |
| 185 | + slice = slice.substr(1, slice.length - 2); |
| 186 | + } |
| 187 | + |
| 188 | + if (slice.includes('""')) { |
| 189 | + // "" Escape processing |
| 190 | + const quotaSequence: number[] = []; |
| 191 | + |
| 192 | + let pos = slice.indexOf('"'); |
| 193 | + while (pos !== -1) { |
| 194 | + quotaSequence.push(pos); |
| 195 | + pos = slice.indexOf('"', pos + 1); |
| 196 | + } |
| 197 | + |
| 198 | + if (quotaSequence.length % 2 !== 0) { |
| 199 | + throw new Error('Number of quotation marks does not match'); |
| 200 | + } |
| 201 | + |
| 202 | + for (let i = 0; i < quotaSequence.length; ) { |
| 203 | + if (quotaSequence[i] !== quotaSequence[i + 1] - 1) { |
| 204 | + throw new Error(`Unescaped " at ${line}`); |
| 205 | + } |
| 206 | + i += 2; |
| 207 | + } |
| 208 | + |
| 209 | + slice = slice.replace(/""/g, '"'); |
| 210 | + } |
| 211 | + |
| 212 | + tokens.push(slice); |
| 213 | + } |
| 214 | + |
| 215 | + arrays.push(deepCopy(tokens)); |
| 216 | + tokens = []; |
| 217 | + } |
| 218 | + return arrays; |
165 | 219 | }
|
166 | 220 |
|
167 | 221 | function isRoleManagerSync(rm: RoleManager): boolean {
|
|
0 commit comments