bool _needsNormalization()

in lib/src/context.dart [370:433]


  bool _needsNormalization(String path) {
    var start = 0;
    final codeUnits = path.codeUnits;
    int? previousPrevious;
    int? previous;

    // Skip past the root before we start looking for snippets that need
    // normalization. We want to normalize "//", but not when it's part of
    // "http://".
    final root = style.rootLength(path);
    if (root != 0) {
      start = root;
      previous = chars.slash;

      // On Windows, the root still needs to be normalized if it contains a
      // forward slash.
      if (style == Style.windows) {
        for (var i = 0; i < root; i++) {
          if (codeUnits[i] == chars.slash) return true;
        }
      }
    }

    for (var i = start; i < codeUnits.length; i++) {
      final codeUnit = codeUnits[i];
      if (style.isSeparator(codeUnit)) {
        // Forward slashes in Windows paths are normalized to backslashes.
        if (style == Style.windows && codeUnit == chars.slash) return true;

        // Multiple separators are normalized to single separators.
        if (previous != null && style.isSeparator(previous)) return true;

        // Single dots and double dots are normalized to directory traversals.
        //
        // This can return false positives for ".../", but that's unlikely
        // enough that it's probably not going to cause performance issues.
        if (previous == chars.period &&
            (previousPrevious == null ||
                previousPrevious == chars.period ||
                style.isSeparator(previousPrevious))) {
          return true;
        }
      }

      previousPrevious = previous;
      previous = codeUnit;
    }

    // Empty paths are normalized to ".".
    if (previous == null) return true;

    // Trailing separators are removed.
    if (style.isSeparator(previous)) return true;

    // Single dots and double dots are normalized to directory traversals.
    if (previous == chars.period &&
        (previousPrevious == null ||
            style.isSeparator(previousPrevious) ||
            previousPrevious == chars.period)) {
      return true;
    }

    return false;
  }