# Windows / Ubuntu 编码与换行 — 深挖审计（第二轮）

| 项 | 内容 |
|----|------|
| 日期 | 2026-06-02 |
| 前置 | `docs/audit/2026-06-02-windows-ubuntu-encoding-audit.md` |
| 目标 | 区分「工作区 CRLF」vs「Git 索引」、堵住运行时 UTF-8/BOM/EOL 漏洞 |

---

## 1. 关键结论

| 问题 | 结论 |
|------|------|
| Ubuntu `git pull` 会带上 CRLF 吗？ | **本轮扫描：Git 索引中 deploy 关键路径 0 个 CR 字节**（`scripts/check_text_eol.py`） |
| Windows 工作区 422 个文件含 `\r`？ | **正常**：`core.autocrlf` 检出时转 CRLF；以 **Git 索引** 为准，不以工作区为准 |
| `.sh` 曾导致 bash 失败？ | 已修 14 个脚本；`check_shell_eol.sh` + `check_text_eol.py` 双门控 |
| 安装向导写 `.env` 会污染 CRLF？ | **已修**：`install.py` 统一 `write_utf8_lf` / `read_utf8_text`（utf-8-sig 去 BOM） |
| MCP 同步 `.env` 会保留 CRLF？ | **已修**：`sync_mysql_mcp_env.py` 读归一化 LF、写 LF |
| 远程读文件 EOL | **增强**：`detect_text_eol()` 识别 LF / CRLF / 经典 Mac `\r` |

---

## 2. 新增基础设施

| 组件 | 路径 | 作用 |
|------|------|------|
| 文本 I/O SSOT | `server/utils/text_io.py` | `read_utf8_text`, `write_utf8_lf`, `detect_text_eol`, `normalize_text_eol` |
| Git 索引门控 | `scripts/check_text_eol.py` | 检查 server/deploy/scripts/frontend 等路径在 **索引** 中无 CR |
| Shell 门控 | `deploy/check_shell_eol.sh` | 仅 `*.sh` |
| 编辑器约定 | `.editorconfig` | `end_of_line = lf`, `charset = utf-8` |
| Git 属性扩展 | `.gitattributes` | `*.vue/ts/py/json/yml/...` 全部 `eol=lf` |

`deploy/pre_deploy_check.sh` Pre-flight 依次执行上述两项 EOL 检查。

---

## 3. 远程文件读写链（Ubuntu 目标机）

```
read-file:  SSH cat → str (UTF-8) → detect_text_eol → JSON
write-file: JSON str → .encode("utf-8") → SFTP/tee bytes（不经过 Windows 换行转换）
```

- **不会**在 Nexus 主机上用 `os.path` 拼远程路径（`posix_paths`）
- **会**按文件内容检测 EOL；编辑器保存时前端按 `eol` 字段还原 `\r\n`
- `cat` 二进制等价：asyncssh 默认解码为 str；非 UTF-8 文件可能替换字符（`errors` 由 SSH 层决定）

---

## 4. 仍须人工遵守的纪律

1. **开发机**：`git config core.autocrlf false`
2. **不要用 Windows 记事本** 编辑 `.env` / `install.sh` 后 SCP 上服务器
3. **前端部署**：WSL/Git Bash 执行 `deploy/deploy-frontend.sh`，不用 PowerShell `tar` 打空包
4. **文档 `*.md` CRLF**：不影响 Ubuntu 运行；逐步 `git add --renormalize '*.md'` 可选

---

## 5. Closure

| H | 判定 | 依据 |
|---|------|------|
| H-CRLF-git | PASS | `check_text_eol.py` 索引 0 CR |
| H-UTF8-install | FIXED | `install.py` → `text_io` |
| H-UTF8-mcp-env | FIXED | `sync_mysql_mcp_env.py` |
| H-EOL-read | ENHANCED | `sync_v2.read_file` + `detect_text_eol` |
| H-gate | PASS | pre_deploy 双 Pre-flight |

## DoD

- [x] Git 索引扫描脚本与结果
- [x] `text_io` 模块 + 单元测试 `tests/test_text_io.py`
- [x] install / sync_v2 / sync_mysql 接入
- [x] `.editorconfig` + 扩展 `.gitattributes`
- [x] changelog 更新

## 验证

```bash
python scripts/check_text_eol.py
bash deploy/check_shell_eol.sh
pytest tests/test_text_io.py -q
```
