Repository: microsoft/edit
File: crates/edit/src/glob.rs (Rust)

Code before:
    let mut next_nx = 0;
    let mut is_double_star = false;

    while px < pattern.len() || nx < name.len() {
        if px < pattern.len() {
            match pattern[px] {
                b'*' => {
                    if pattern.get(px + 1) == Some(&b'*') {
                        // doublestar - matches any characters including /
                        next_px = px;
                        next_nx = nx + 1;
                        is_double_star = true;
                        px += 2;

                        // For convenience, /**/  also matches /.
                        if px >= 3
                            && px < pattern.len()
                            && pattern[px] == b'/'
                            && pattern[px - 3] == b'/'
                        {
                            px += 1;
                        }
                    } else {
                        // single star - does not match path separators
                        // Try to match at nx. If that doesn't work out, restart at nx+1 next.
                        next_px = px;
                        next_nx = nx + 1;
                        px += 1;
                    }
                    continue;
                }
                c => {
                    // ordinary character
                    if nx < name.len() && name[nx].eq_ignore_ascii_case(&c) {
                        px += 1;
                        nx += 1;
                        continue;
                    }
                }
            }
        }

        // Mismatch. Maybe restart.
        if next_nx > 0
            && next_nx <= name.len()
            && (is_double_star || !is_separator(name[next_nx - 1] as char))
        {
            px = next_px;
            nx = next_nx;
            continue;
        }

Review comment (bug):
You never reset is_double_star. I feel like that means `**/foo/*/bar` will match `a/b/c/foo/d/e/f/bar` incorrectly

Code after:
    let mut next_nx = 0;
    let mut is_double_star = false;

    while px < pattern.len() || nx < name.len() {
        if px < pattern.len() {
            match pattern[px] {
                b'*' => {
                    // Try to match at nx. If that doesn't work out, restart at nx+1 next.
                    next_px = px;
                    next_nx = nx + 1;
                    px += 1;
                    is_double_star = false;

                    if px < pattern.len() && pattern[px] == b'*' {
                        px += 1;
                        is_double_star = true;

                        // For convenience, /**/ also matches /
                        if px >= 3
                            && px < pattern.len()
                            && pattern[px] == b'/'
                            && pattern[px - 3] == b'/'
                        {
                            px += 1;
                        }
                    }
                    continue;
                }
                c => {
                    if nx < name.len() && name[nx].eq_ignore_ascii_case(&c) {
                        px += 1;
                        nx += 1;
                        continue;
                    }
                }
            }
        }

        // Mismatch. Maybe restart.
        if next_nx > 0
            && next_nx <= name.len()
            && (is_double_star || !is_separator(name[next_nx - 1] as char))
        {
            px = next_px;
            nx = next_nx;
            continue;
        }

        return false;
    }