-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTest-EncodingGate.ps1
More file actions
99 lines (86 loc) · 3.03 KB
/
Test-EncodingGate.ps1
File metadata and controls
99 lines (86 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
[CmdletBinding()]
param(
[string]$Root = ".",
[string]$OutputJson = "",
[int]$MaxBytes = 2097152
)
$ErrorActionPreference = "Stop"
$rootItem = Get-Item -LiteralPath $Root
$rootFull = $rootItem.FullName
$textExtensions = @(".md", ".txt", ".json", ".html", ".htm", ".js", ".jsx", ".ts", ".tsx", ".yml", ".yaml", ".ps1", ".css")
$excludePattern = "\\(\.git|node_modules|__pycache__|\.venv|venv)\\"
$selfPatternFiles = @("Test-EncodingGate.ps1", "Invoke-WindowsSilkyAudit.ps1")
function New-PatternFromCodePoint {
param([int[]]$CodePoints)
$value = ""
foreach ($point in $CodePoints) {
$value += [string]([char]$point)
}
return $value
}
$patterns = @(
(New-PatternFromCodePoint @(0x951F, 0x65A4, 0x62F7)),
(New-PatternFromCodePoint @(0xFFFD)),
(New-PatternFromCodePoint @(0x00C3)),
(New-PatternFromCodePoint @(0x00C2)),
(New-PatternFromCodePoint @(0x00E2, 0x20AC)),
(New-PatternFromCodePoint @(0x00E4, 0x00B8)),
(New-PatternFromCodePoint @(0x00E5, 0x203A)),
(New-PatternFromCodePoint @(0x00E7, 0x0161)),
(New-PatternFromCodePoint @(0x7ECB)),
(New-PatternFromCodePoint @(0x6D60))
)
function Convert-ToRelativePath {
param([string]$Path, [string]$Base)
$baseUri = New-Object System.Uri(($Base.TrimEnd("\") + "\"))
$pathUri = New-Object System.Uri($Path)
return [System.Uri]::UnescapeDataString($baseUri.MakeRelativeUri($pathUri).ToString()).Replace("/", "\")
}
$findings = New-Object System.Collections.Generic.List[object]
$files = Get-ChildItem -LiteralPath $rootFull -Recurse -File -Force -ErrorAction SilentlyContinue |
Where-Object {
$textExtensions -contains $_.Extension.ToLowerInvariant() -and
$_.Length -le $MaxBytes -and
$_.FullName -notmatch $excludePattern -and
$selfPatternFiles -notcontains $_.Name
}
foreach ($file in $files) {
$text = ""
try {
$text = Get-Content -LiteralPath $file.FullName -Raw -Encoding UTF8 -ErrorAction Stop
}
catch {
continue
}
$matched = @()
foreach ($pattern in $patterns) {
if ($text.Contains([string]$pattern)) {
$matched += $pattern
}
}
if ($matched.Count -gt 0) {
$findings.Add([ordered]@{
path = Convert-ToRelativePath -Path $file.FullName -Base $rootFull
bytes = $file.Length
patterns = $matched
action = "Review this file before publishing."
})
}
}
$result = [ordered]@{
schema = "make_windows_silky_Patch.encoding-gate.v1"
root = $rootFull
generated_at = (Get-Date).ToString("o")
finding_count = $findings.Count
findings = @($findings.ToArray())
}
if ($OutputJson) {
$result | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $OutputJson -Encoding UTF8
}
if ($findings.Count -gt 0) {
Write-Host "Encoding gate failed: $($findings.Count) possible mojibake finding(s)." -ForegroundColor Red
$findings | Select-Object -First 25 | Format-Table -AutoSize
exit 1
}
Write-Host "Encoding gate passed." -ForegroundColor Green
exit 0