CodeSampleX

샘플

minimatch 10.1.1: Unescape glob pattern strings with minimatch.unescape across windowsPathsNoEscape path mode and magicalBraces configurations

검증된 샘플 — npm minimatch 10.1.1: Unescape glob pattern strings with minimatch.unescape across windowsPathsNoEscape path mode and magicalBraces configurations.…

sha256:03eabe054f3c93d859e0a70ed50e293fad84864a382960bcc89fd0f55fdf4ca8

이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다. 통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다. MIT-0

실행 증거

선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.

증거 기준
서명된 컨트랙트 통과
검증 영수증
2
빌드한 서명 키
2
선언된 환경 node linux x64 node node npm

검증 실행 환경

환경 컨트랙트 단계 실행일
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-17
node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18

케이스

HOW
목표
Unescape glob pattern strings with minimatch.unescape across windowsPathsNoEscape path mode and magicalBraces configurations
패키지
심벌
  • minimatch.unescape
환경
node
생성일
2026-08-17T22:46:35Z

컨트랙트

  1. minimatch.unescape preserves backslash sequences under windowsPathsNoEscape mode because backslashes are treated as path separators rather than escape characters
  2. minimatch.unescape strips single-character bracket escapes while leaving multi-character bracket character classes and forward slashes untouched
  3. minimatch.unescape defaults magicalBraces to true which strips brace escapes, but retains brace escapes when magicalBraces is explicitly set to false
  4. minimatch.unescape leaves adjacent bracket wraps unescaped in standard mode due to preceding character consumption in the replacement regex
  5. minimatch.unescape unescapes backslash-escaped opening brackets to literal brackets rather than stripping the inner character wrap

파일

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • src/index.mjs
  • test/contract.mjs

소스 아티팩트 내려받기 (tar.gz)

소스

NOTES.md
# Minimatch Unescape Semantics and Edge Cases

## Search Findings

Querying known solutions returned `sha256:585ab2a8ea43909cb7e47145ba967133e7da688e33baa7e055319539c3675105`, which demonstrated general glob matching features across multiple symbols. This sample investigates the exact contract, option interactions, and pattern parsing rules of `minimatch.unescape`.

## Pinned Version

- `minimatch`: `10.1.1`

## Observed Behavior

`minimatch.unescape` is exposed both as a named export (`unescape`) and as a property on the default/namespace export (`minimatch.unescape`).

### 1. Windows Path Mode (`windowsPathsNoEscape: true`)

When `windowsPathsNoEscape` is enabled:
- Backslashes (`\`) are treated strictly as path separators, not escape characters. Backslash escape sequences such as `\*` or `\?` are left untouched.
- Single-character bracket wraps used by `minimatch.escape` (such as `[*]`, `[?]`) are unescaped.
- Backslashes inside brackets (such as `[\\]`) are not stripped.

### 2. Standard Mode vs. Non-Magic Characters

In standard mode (`windowsPathsNoEscape: false`):
- Backslashes before non-slash characters are stripped (`\*` -> `*`, `\?` -> `?`, `\(` -> `(`, `\)` -> `)`, `\[` -> `[`, `\]` -> `]`).
- Forward slashes are never unescaped: `\/` remains `\/` and `[/]` remains `[/]`.
- Multi-character character classes (such as `[abc]`, `[0-9]`, `[!a-z]`) are preserved without modification because the bracket matcher only matches single non-slash characters `[([^\/\\])]`.

### 3. Asymmetric Defaults for `magicalBraces`

While `minimatch.escape` defaults `magicalBraces` to `false` (leaving braces untouched), `minimatch.unescape` defaults `magicalBraces` to `true`.
- Default (`magicalBraces: true`): `\{a,b\}` unescapes to `{a,b}`, and `[{]a,b[}]` unescapes to `{a,b}`.
- Explicit `magicalBraces: false`: Brace escapes are preserved as literal escapes (`\{a,b\}` and `[{]a,b[}]`), while other escaped wildcards (such as `\*`) are still unescaped.

### 4. Consecutive Bracket Replacement Boundary

In standard mode, the unescape regex uses `((?!\\).|^)\[([^\/\\])\]` to avoid unescaping backslash-escaped brackets. Because `((?!\\).|^)` consumes the preceding character during replacement, consecutive bracket escapes like `[*][*]` only unescape the first bracket, yielding `*[*]`. When separated by other characters (`[*]a[*]`), both are unescaped to `*a*`. In `windowsPathsNoEscape` mode, the regex does not capture preceding characters, so `[*][*]` resolves to `**`.

### 5. Escaped Bracket Wraps

When a bracket escape is prefixed with a backslash (`\[*]`), the leading backslash escapes the opening bracket, resulting in literal `[*]`.

## Failure Modes of Wrong Expectations

1. **Backslashes in Windows Path Mode**: A model assuming `unescape` strips backslashes regardless of mode will generate incorrect paths when `windowsPathsNoEscape: true` is active, failing assertions when backslashes persist.
2. **Magical Braces Default**: Expecting `unescape` to mirror `escape`'s default `magicalBraces: false` leads to unexpected stripping of brace escapes in standard patterns.
3. **Adjacent Bracket Classes**: Assuming consecutive single-character bracket escapes `[*][*]` normalize to `**` in standard mode results in unexpected leftover bracket notation `*[*]`.
csx.json
{"case":{"believed":"minimatch.unescape strips backslash escape sequences under windowsPathsNoEscape mode and preserves brace escapes by default","caseId":"case:sha256:51c8867514ce9543a0446577e08adf3c6b1835b2eef8937c763ca9249748a5c6","contract":["minimatch.unescape preserves backslash sequences under windowsPathsNoEscape mode because backslashes are treated as path separators rather than escape characters","minimatch.unescape strips single-character bracket escapes while leaving multi-character bracket character classes and forward slashes untouched","minimatch.unescape defaults magicalBraces to true which strips brace escapes, but retains brace escapes when magicalBraces is explicitly set to false","minimatch.unescape leaves adjacent bracket wraps unescaped in standard mode due to preceding character consumption in the replacement regex","minimatch.unescape unescapes backslash-escaped opening brackets to literal brackets rather than stripping the inner character wrap"],"goal":"Unescape glob pattern strings with minimatch.unescape across windowsPathsNoEscape path mode and magicalBraces configurations","kind":"HOW","packages":["pkg:npm/minimatch@10.1.1"],"schemaVersion":1,"symbols":["minimatch.unescape"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/minimatch@10.1.1"],"schemaVersion":1,"symbols":["minimatch.unescape"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "minimatch-unescape-contract",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "minimatch-unescape-contract",
      "version": "1.0.0",
      "dependencies": {
        "minimatch": "10.1.1"
      }
    },
    "node_modules/@isaacs/balanced-match": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
      "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
      "license": "MIT",
      "engines": {
        "node": "20 || >=22"
      }
    },
    "node_modules/@isaacs/brace-expansion": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz",
      "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==",
      "license": "MIT",
      "dependencies": {
        "@isaacs/balanced-match": "^4.0.1"
      },
      "engines": {
        "node": "20 || >=22"
      }
    },
    "node_modules/minimatch": {
      "version": "10.1.1",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
      "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
      "license": "BlueOak-1.0.0",
      "dependencies": {
        "@isaacs/brace-expansion": "^5.0.0"
      },
      "engines": {
        "node": "20 || >=22"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    }
  }
}
package.json
{
  "name": "minimatch-unescape-contract",
  "private": true,
  "type": "module",
  "dependencies": {
    "minimatch": "10.1.1"
  }
}
src/index.mjs
import { minimatch, unescape } from 'minimatch';

export function unescapePattern(pattern, options) {
  return unescape(pattern, options);
}

export function unescapeFromMinimatchObject(pattern, options) {
  return minimatch.unescape(pattern, options);
}
test/contract.mjs
import { strict as assert } from 'node:assert';
import { minimatch, unescape } from 'minimatch';
import { unescapeFromMinimatchObject, unescapePattern } from '../src/index.mjs';

// Verify minimatch.unescape is exposed as a property and matches named export
assert.strictEqual(minimatch.unescape, unescape);
assert.strictEqual(typeof minimatch.unescape, 'function');

// 1. windowsPathsNoEscape mode: backslashes are path separators and not escape chars,
// while single-character bracket escapes are stripped.
const winEscaped = 'dir\\subdir\\[*]\\file\\[?].txt';
assert.strictEqual(
  unescapePattern(winEscaped, { windowsPathsNoEscape: true }),
  'dir\\subdir\\*\\file\\?.txt'
);
assert.strictEqual(
  unescapePattern('\\*\\?', { windowsPathsNoEscape: true }),
  '\\*\\?'
);
assert.strictEqual(
  unescapePattern('[\\]', { windowsPathsNoEscape: true }),
  '[\\]'
);
assert.strictEqual(
  unescapePattern('[*][*]', { windowsPathsNoEscape: true }),
  '**'
);

// 2. Standard mode: backslashes and separated single-character bracket escapes are stripped,
// but forward slashes and multi-character bracket classes are never unescaped.
assert.strictEqual(unescapePattern('\\*\\?\\[\\]\\(\\)'), '*?[]()');
assert.strictEqual(unescapePattern('[*]a[?]b[(]c[)]'), '*a?b(c)');
assert.strictEqual(unescapePattern('\\/'), '\\/');
assert.strictEqual(unescapePattern('[/]'), '[/]');
assert.strictEqual(unescapePattern('[abc]'), '[abc]');
assert.strictEqual(unescapePattern('[0-9]'), '[0-9]');
assert.strictEqual(unescapePattern('[!a-z]'), '[!a-z]');

// 3. Standard mode adjacent bracket trap: consuming preceding char leaves adjacent brackets unescaped
assert.strictEqual(unescapePattern('[*][*]'), '*[*]');

// 4. magicalBraces handling: unescape defaults magicalBraces to true (unlike escape),
// stripping brace escapes, but retains them when magicalBraces is explicitly false.
assert.strictEqual(unescapePattern('\\{a,b\\}'), '{a,b}');
assert.strictEqual(unescapePattern('[{]a,b[}]'), '{a,b}');
assert.strictEqual(
  unescapePattern('\\{a,b\\}', { magicalBraces: false }),
  '\\{a,b\\}'
);
assert.strictEqual(
  unescapePattern('[{]a,b[}]', { magicalBraces: false }),
  '[{]a,b[}]'
);
assert.strictEqual(
  unescapePattern('\\*\\{a,b\\}', { magicalBraces: false }),
  '*\\{a,b\\}'
);

// 5. Escaped bracket wraps: backslash before bracket unescapes outer bracket rather than inner wildcard
assert.strictEqual(unescapePattern('\\[*]'), '[*]');

// 6. Verification through minimatch.unescape property invocation
assert.strictEqual(
  unescapeFromMinimatchObject('\\[a\\]'),
  '[a]'
);
assert.strictEqual(
  unescapeFromMinimatchObject('src/\\[*\\]/*.js'),
  'src/[*]/*.js'
);

오리진 시더

csx-seed