Ignore:
Timestamp:
09/19/26 10:30:30 (11 days ago)
Author:
Klimentina Efremova <klimentina08642@…>
Branches:
finki-main, main
Children:
06ebe74
Parents:
62b2964
Message:

Turned database from SQLite to PostgressSQL, updated database changes from Phase 1 and 2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • node_modules/picomatch/lib/parse.js

    r62b2964 r33517cc  
    4444const syntaxError = (type, char) => {
    4545  return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
     46};
     47
     48const splitTopLevel = input => {
     49  const parts = [];
     50  let bracket = 0;
     51  let paren = 0;
     52  let quote = 0;
     53  let value = '';
     54  let escaped = false;
     55
     56  for (const ch of input) {
     57    if (escaped === true) {
     58      value += ch;
     59      escaped = false;
     60      continue;
     61    }
     62
     63    if (ch === '\\') {
     64      value += ch;
     65      escaped = true;
     66      continue;
     67    }
     68
     69    if (ch === '"') {
     70      quote = quote === 1 ? 0 : 1;
     71      value += ch;
     72      continue;
     73    }
     74
     75    if (quote === 0) {
     76      if (ch === '[') {
     77        bracket++;
     78      } else if (ch === ']' && bracket > 0) {
     79        bracket--;
     80      } else if (bracket === 0) {
     81        if (ch === '(') {
     82          paren++;
     83        } else if (ch === ')' && paren > 0) {
     84          paren--;
     85        } else if (ch === '|' && paren === 0) {
     86          parts.push(value);
     87          value = '';
     88          continue;
     89        }
     90      }
     91    }
     92
     93    value += ch;
     94  }
     95
     96  parts.push(value);
     97  return parts;
     98};
     99
     100const isPlainBranch = branch => {
     101  let escaped = false;
     102
     103  for (const ch of branch) {
     104    if (escaped === true) {
     105      escaped = false;
     106      continue;
     107    }
     108
     109    if (ch === '\\') {
     110      escaped = true;
     111      continue;
     112    }
     113
     114    if (/[?*+@!()[\]{}]/.test(ch)) {
     115      return false;
     116    }
     117  }
     118
     119  return true;
     120};
     121
     122const normalizeSimpleBranch = branch => {
     123  let value = branch.trim();
     124  let changed = true;
     125
     126  while (changed === true) {
     127    changed = false;
     128
     129    if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
     130      value = value.slice(2, -1);
     131      changed = true;
     132    }
     133  }
     134
     135  if (!isPlainBranch(value)) {
     136    return;
     137  }
     138
     139  return value.replace(/\\(.)/g, '$1');
     140};
     141
     142const hasRepeatedCharPrefixOverlap = branches => {
     143  const values = branches.map(normalizeSimpleBranch).filter(Boolean);
     144
     145  for (let i = 0; i < values.length; i++) {
     146    for (let j = i + 1; j < values.length; j++) {
     147      const a = values[i];
     148      const b = values[j];
     149      const char = a[0];
     150
     151      if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) {
     152        continue;
     153      }
     154
     155      if (a === b || a.startsWith(b) || b.startsWith(a)) {
     156        return true;
     157      }
     158    }
     159  }
     160
     161  return false;
     162};
     163
     164const parseRepeatedExtglob = (pattern, requireEnd = true) => {
     165  if ((pattern[0] !== '+' && pattern[0] !== '*') || pattern[1] !== '(') {
     166    return;
     167  }
     168
     169  let bracket = 0;
     170  let paren = 0;
     171  let quote = 0;
     172  let escaped = false;
     173
     174  for (let i = 1; i < pattern.length; i++) {
     175    const ch = pattern[i];
     176
     177    if (escaped === true) {
     178      escaped = false;
     179      continue;
     180    }
     181
     182    if (ch === '\\') {
     183      escaped = true;
     184      continue;
     185    }
     186
     187    if (ch === '"') {
     188      quote = quote === 1 ? 0 : 1;
     189      continue;
     190    }
     191
     192    if (quote === 1) {
     193      continue;
     194    }
     195
     196    if (ch === '[') {
     197      bracket++;
     198      continue;
     199    }
     200
     201    if (ch === ']' && bracket > 0) {
     202      bracket--;
     203      continue;
     204    }
     205
     206    if (bracket > 0) {
     207      continue;
     208    }
     209
     210    if (ch === '(') {
     211      paren++;
     212      continue;
     213    }
     214
     215    if (ch === ')') {
     216      paren--;
     217
     218      if (paren === 0) {
     219        if (requireEnd === true && i !== pattern.length - 1) {
     220          return;
     221        }
     222
     223        return {
     224          type: pattern[0],
     225          body: pattern.slice(2, i),
     226          end: i
     227        };
     228      }
     229    }
     230  }
     231};
     232
     233const getStarExtglobSequenceOutput = pattern => {
     234  let index = 0;
     235  const chars = [];
     236
     237  while (index < pattern.length) {
     238    const match = parseRepeatedExtglob(pattern.slice(index), false);
     239
     240    if (!match || match.type !== '*') {
     241      return;
     242    }
     243
     244    const branches = splitTopLevel(match.body).map(branch => branch.trim());
     245    if (branches.length !== 1) {
     246      return;
     247    }
     248
     249    const branch = normalizeSimpleBranch(branches[0]);
     250    if (!branch || branch.length !== 1) {
     251      return;
     252    }
     253
     254    chars.push(branch);
     255    index += match.end + 1;
     256  }
     257
     258  if (chars.length < 1) {
     259    return;
     260  }
     261
     262  const source = chars.length === 1
     263    ? utils.escapeRegex(chars[0])
     264    : `[${chars.map(ch => utils.escapeRegex(ch)).join('')}]`;
     265
     266  return `${source}*`;
     267};
     268
     269const repeatedExtglobRecursion = pattern => {
     270  let depth = 0;
     271  let value = pattern.trim();
     272  let match = parseRepeatedExtglob(value);
     273
     274  while (match) {
     275    depth++;
     276    value = match.body.trim();
     277    match = parseRepeatedExtglob(value);
     278  }
     279
     280  return depth;
     281};
     282
     283const analyzeRepeatedExtglob = (body, options) => {
     284  if (options.maxExtglobRecursion === false) {
     285    return { risky: false };
     286  }
     287
     288  const max =
     289    typeof options.maxExtglobRecursion === 'number'
     290      ? options.maxExtglobRecursion
     291      : constants.DEFAULT_MAX_EXTGLOB_RECURSION;
     292
     293  const branches = splitTopLevel(body).map(branch => branch.trim());
     294
     295  if (branches.length > 1) {
     296    if (
     297      branches.some(branch => branch === '') ||
     298      branches.some(branch => /^[*?]+$/.test(branch)) ||
     299      hasRepeatedCharPrefixOverlap(branches)
     300    ) {
     301      return { risky: true };
     302    }
     303  }
     304
     305  for (const branch of branches) {
     306    const safeOutput = getStarExtglobSequenceOutput(branch);
     307    if (safeOutput) {
     308      return { risky: true, safeOutput };
     309    }
     310
     311    if (repeatedExtglobRecursion(branch) > max) {
     312      return { risky: true };
     313    }
     314  }
     315
     316  return { risky: false };
    46317};
    47318
    … …  
    227498    token.parens = state.parens;
    228499    token.output = state.output;
     500    token.startIndex = state.index;
     501    token.tokensIndex = tokens.length;
    229502    const output = (opts.capture ? '(' : '') + token.open;
    230503
    … …  
    236509
    237510  const extglobClose = token => {
     511    const literal = input.slice(token.startIndex, state.index + 1);
     512    const body = input.slice(token.startIndex + 2, state.index);
     513    const analysis = analyzeRepeatedExtglob(body, opts);
     514
     515    if ((token.type === 'plus' || token.type === 'star') && analysis.risky) {
     516      const safeOutput = analysis.safeOutput
     517        ? (token.output ? '' : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput)
     518        : undefined;
     519      const open = tokens[token.tokensIndex];
     520
     521      open.type = 'text';
     522      open.value = literal;
     523      open.output = safeOutput || utils.escapeRegex(literal);
     524
     525      for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
     526        tokens[i].value = '';
     527        tokens[i].output = '';
     528        delete tokens[i].suffix;
     529      }
     530
     531      state.output = token.output + open.output;
     532      state.backtrack = true;
     533
     534      push({ type: 'paren', extglob: true, value, output: '' });
     535      decrement('parens');
     536      return;
     537    }
     538
    238539    let output = token.close + (opts.capture ? ')' : '');
    239540    let rest;
Note: See TracChangeset for help on using the changeset viewer.