Skip to content

Commit 4c75f07

Browse files
authored
Merge pull request #1063 from GitGuardian/severine/scrt-5358-ggshield-error-with-emojis-in-file-name
Fix ggshield error with emojis in file name
2 parents e35a6c4 + d3f3a41 commit 4c75f07

File tree

4 files changed

+191
-1
lines changed

4 files changed

+191
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Fixed
2+
3+
- Files with emojis in their name are now handled properly.

ggshield/utils/git_shell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def git(
204204
try:
205205
logger.debug("command=%s timeout=%d", command, timeout)
206206
result = subprocess.run(
207-
[_get_git_path()] + command,
207+
[_get_git_path(), "-c", "core.quotePath=false"] + command,
208208
check=check,
209209
capture_output=True,
210210
timeout=timeout,
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
interactions:
2+
- request:
3+
body: null
4+
headers:
5+
Accept:
6+
- '*/*'
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
User-Agent:
12+
- pygitguardian/1.20.0 (Darwin;py3.11.10) ggshield
13+
method: GET
14+
uri: https://api.gitguardian.com/v1/metadata
15+
response:
16+
body:
17+
string:
18+
'{"version":"v2.163.0","preferences":{"marketplaces__aws_product_url":"http://aws.amazon.com/marketplace/pp/prodview-mrmulzykamba6","on_premise__restrict_signup":true,"on_premise__is_email_server_configured":true,"on_premise__default_sso_config_api_id":null,"on_premise__default_sso_config_force_sso":null,"onboarding__segmentation_v1_enabled":true,"general__maximum_payload_size":26214400,"general__mutual_tls_mode":"disabled","general__signup_enabled":true},"secret_scan_preferences":{"maximum_documents_per_scan":20,"maximum_document_size":1048576},"remediation_messages":{"pre_commit":">
19+
How to remediate\n\n Since the secret was detected before the commit was
20+
made:\n 1. replace the secret with its reference (e.g. environment variable).\n 2.
21+
commit again.\n\n> [Apply with caution] If you want to bypass ggshield (false
22+
positive or other reason), run:\n - if you use the pre-commit framework:\n\n SKIP=ggshield
23+
git commit -m \"<your message>\"\n ","pre_push":"> How to remediate\n\n Since
24+
the secret was detected before the push BUT after the commit, you need to:\n 1.
25+
rewrite the git history making sure to replace the secret with its reference
26+
(e.g. environment variable).\n 2. push again.\n\n To prevent having to rewrite
27+
git history in the future, setup ggshield as a pre-commit hook:\n https://docs.gitguardian.com/ggshield-docs/integrations/git-hooks/pre-commit\n\n>
28+
[Apply with caution] If you want to bypass ggshield (false positive or other
29+
reason), run:\n - if you use the pre-commit framework:\n\n SKIP=ggshield-push
30+
git push","pre_receive":"> How to remediate\n\n A pre-receive hook set server
31+
side prevented you from pushing secrets.\n\n Since the secret was detected
32+
during the push BUT after the commit, you need to:\n 1. rewrite the git history
33+
making sure to replace the secret with its reference (e.g. environment variable).\n 2.
34+
push again.\n\n To prevent having to rewrite git history in the future, setup
35+
ggshield as a pre-commit hook:\n https://docs.gitguardian.com/ggshield-docs/integrations/git-hooks/pre-commit\n\n>
36+
[Apply with caution] If you want to bypass ggshield (false positive or other
37+
reason), run:\n\n git push -o breakglass"}}'
38+
headers:
39+
access-control-expose-headers:
40+
- X-App-Version
41+
allow:
42+
- GET, HEAD, OPTIONS
43+
content-length:
44+
- '2198'
45+
content-type:
46+
- application/json
47+
cross-origin-opener-policy:
48+
- same-origin
49+
date:
50+
- Thu, 06 Mar 2025 16:36:14 GMT
51+
referrer-policy:
52+
- strict-origin-when-cross-origin
53+
server:
54+
- istio-envoy
55+
strict-transport-security:
56+
- max-age=31536000; includeSubDomains
57+
transfer-encoding:
58+
- chunked
59+
vary:
60+
- Accept-Encoding,Cookie
61+
x-app-version:
62+
- v2.163.0
63+
x-content-type-options:
64+
- nosniff
65+
- nosniff
66+
x-envoy-upstream-service-time:
67+
- '36'
68+
x-frame-options:
69+
- DENY
70+
- SAMEORIGIN
71+
x-secrets-engine-version:
72+
- 2.133.0
73+
x-xss-protection:
74+
- 1; mode=block
75+
status:
76+
code: 200
77+
message: OK
78+
- request:
79+
body:
80+
'[{"filename": "commit://staged/my_\ud83d\ude0a_emoji_file.txt", "document":
81+
"@@ -1 +1 @@\n-Initial content\n\\ No newline at end of file\n+Modified content\n\\
82+
No newline at end of file"}]'
83+
headers:
84+
Accept:
85+
- '*/*'
86+
Accept-Encoding:
87+
- gzip, deflate
88+
Connection:
89+
- keep-alive
90+
Content-Length:
91+
- '188'
92+
Content-Type:
93+
- application/json
94+
GGShield-Command-Id:
95+
- c59543a5-978d-4b24-99e0-8c748921a2ac
96+
GGShield-Command-Path:
97+
- cli secret scan pre-commit
98+
GGShield-OS-Name:
99+
- darwin
100+
GGShield-OS-Version:
101+
- 'Darwin Kernel Version 24.3.0: Thu Jan 2 20:23:36 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T8112'
102+
GGShield-Python-Version:
103+
- 3.11.10
104+
GGShield-Version:
105+
- 1.37.0
106+
User-Agent:
107+
- pygitguardian/1.20.0 (Darwin;py3.11.10) ggshield
108+
mode:
109+
- pre_commit
110+
scan_options:
111+
- '{"show_secrets": false, "ignored_detectors_count": 0, "ignored_matches_count":
112+
0, "ignored_paths_count": 14, "ignore_known_secrets": false, "with_incident_details":
113+
false, "has_prereceive_remediation_message": false, "all_secrets": false}'
114+
method: POST
115+
uri: https://api.gitguardian.com/v1/multiscan?all_secrets=True
116+
response:
117+
body:
118+
string: '[{"policy_break_count":0,"policies":["Secrets detection"],"policy_breaks":[],"is_diff":true}]'
119+
headers:
120+
access-control-expose-headers:
121+
- X-App-Version
122+
allow:
123+
- POST, OPTIONS
124+
content-length:
125+
- '93'
126+
content-type:
127+
- application/json
128+
cross-origin-opener-policy:
129+
- same-origin
130+
date:
131+
- Thu, 06 Mar 2025 16:36:15 GMT
132+
referrer-policy:
133+
- strict-origin-when-cross-origin
134+
server:
135+
- istio-envoy
136+
strict-transport-security:
137+
- max-age=31536000; includeSubDomains
138+
vary:
139+
- Cookie
140+
x-app-version:
141+
- v2.163.0
142+
x-content-type-options:
143+
- nosniff
144+
- nosniff
145+
x-envoy-upstream-service-time:
146+
- '70'
147+
x-frame-options:
148+
- DENY
149+
- SAMEORIGIN
150+
x-secrets-engine-version:
151+
- 2.133.0
152+
x-xss-protection:
153+
- 1; mode=block
154+
status:
155+
code: 200
156+
message: OK
157+
version: 1

tests/unit/cmd/scan/test_precommit.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33

44
import pytest
55

6+
from ggshield.__main__ import cli
67
from ggshield.cmd.secret.scan.precommit import (
78
check_is_merge_with_conflict,
89
check_is_merge_without_conflict,
910
get_merge_branch_from_reflog,
1011
)
12+
from ggshield.utils.os import cd
1113
from tests.repository import Repository
14+
from tests.unit.conftest import assert_invoke_ok, my_vcr
1215

1316

1417
def test_is_merge_not_merge(tmp_path):
@@ -98,3 +101,30 @@ def test_get_merge_branch_from_reflog(monkeypatch):
98101
monkeypatch.setenv("GIT_REFLOG_ACTION", "merge master") # Simulate merge
99102
assert check_is_merge_without_conflict()
100103
assert get_merge_branch_from_reflog() == "master"
104+
105+
106+
@my_vcr.use_cassette("test_emoji_filename")
107+
def test_precommit_with_emoji_filename(tmp_path, cli_fs_runner):
108+
"""
109+
GIVEN a repository with a staged diff on a file with an emoji in its name
110+
WHEN the precommit command is run
111+
THEN it executes successfully
112+
"""
113+
# Set up repository
114+
repo = Repository.create(tmp_path)
115+
116+
# Create a file with emoji in the name
117+
emoji_file = tmp_path / "my_😊_emoji_file.txt"
118+
emoji_file.write_text("Initial content")
119+
repo.add(".")
120+
repo.create_commit("Initial commit with emoji file")
121+
122+
# Modify the file and stage the changes
123+
emoji_file.write_text("Modified content")
124+
repo.add(".")
125+
126+
# Run the precommit command
127+
with cd(repo.path):
128+
result = cli_fs_runner.invoke(cli, ["secret", "scan", "pre-commit"])
129+
# Verify the command executed successfully
130+
assert_invoke_ok(result)

0 commit comments

Comments
 (0)