Skip to content

Hotfix/mac sandbox export bug#19

Merged
amemya merged 6 commits into
mainfrom
hotfix/mac-sandbox-export-bug
May 18, 2026
Merged

Hotfix/mac sandbox export bug#19
amemya merged 6 commits into
mainfrom
hotfix/mac-sandbox-export-bug

Conversation

@amemya
Copy link
Copy Markdown
Owner

@amemya amemya commented May 17, 2026

resolved #18

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1e54e7b5-9475-4154-b85b-f30a37214374

📥 Commits

Reviewing files that changed from the base of the PR and between 2556bfd and 7cb948a.

📒 Files selected for processing (1)
  • handler.go

📝 Walkthrough

Summary by CodeRabbit

New Features

  • ファイルアップロード時のセキュリティ検証機能を追加しました

Improvements

  • ファイル保存処理の信頼性が向上し、エラーハンドリングが改善されました
  • ファイル転送方式が最適化されました

Walkthrough

Canvas 由来の画像をフロントで Blob→ArrayBuffer に変換して /api/save に POST し、サーバは受信をシステムテンポラリへストリームして先頭バイトで MIME を検証、検証後に os.Rename を試行し失敗時はコピー+Sync で保存するように変更されました。

Changes

Canvas Export API ペイロード形式とバックエンド検証・保存フロー

Layer / File(s) Summary
フロントエンド ArrayBuffer 変換
frontend/src/App.tsx
Canvas 由来の Blobblob.arrayBuffer()ArrayBuffer に変換し、/api/save の POST body に ArrayBuffer を送るように変更(macOS WebKit の空ペイロード注意コメント追加)。
バックエンド import 削除とテンポラリ作成・ストリーミング受信
handler.go
path/filepath の import を削除。os.CreateTemp("", ...) でテンポリを作成し、リクエストボディを io.Copy でテンポリへストリーミング。書き込みが0の場合は400を返す分岐追加。
バックエンド MIME 検証(先頭バイト読み取り)
handler.go
テンポラリ先頭最大512バイトを読み http.DetectContentTypeexpectedMime と照合。先頭が読めない場合は500、不一致は400を返す。
バックエンド 確定保存(rename → コピー + Sync)
handler.go
検証成功後は os.Rename(tmpPath, savePath) を優先、失敗時はテンポリを開いて os.Create(savePath)io.Copyout.Sync() のフォールバックで確定保存。各失敗箇所で500を返す。

Sequence Diagram

sequenceDiagram
  participant Frontend
  participant Server as handleSave
  participant FileSystem
  Frontend->>Server: POST /api/save<br/>(ArrayBuffer body)
  Server->>Server: Create temp file (os.CreateTemp)<br/>Stream request body into temp (io.Copy)
  Server->>Server: Read up to 512 bytes from temp<br/>http.DetectContentType
  alt validation success
    Server->>FileSystem: Rename temp → savePath (os.Rename)
    alt rename fails
      Server->>FileSystem: Create savePath, copy from temp (io.Copy)
      Server->>FileSystem: out.Sync()
    end
  else validation failure
    Server->>Frontend: HTTP 400 / 500
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • amemya/ExifFrame#15: frontend と handler.go の /api/save バイナリ転送とサーバ側ストリーミング/検証ロジックが関連。
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PRのタイトルは「Hotfix/mac sandbox export bug」であり、変更内容のexport機能修復とmacOS関連のサンドボックスの問題に直接関連しており、主要な変更を適切に要約しています。
Description check ✅ Passed PR説明は「resolved #18」という簡潔な記述で、linkedIssue #18(export機能の復旧)に直接関連しており、対象とする問題を明確に参照しています。
Linked Issues check ✅ Passed コード変更は#18で説明されているexport機能の復旧に対応しており、フロントエンドではBlob→ArrayBuffer変換、バックエンドではテンポラリディレクトリ変更とセキュリティ検証を実装し、export機能の修復要件を満たしています。
Out of Scope Changes check ✅ Passed 全ての変更はexport機能の復旧という#18の目標に関連しており、フロントエンドのBlob変換とバックエンドのテンポラリファイル処理・セキュリティ検証はいずれもexport修復の必要な実装です。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/mac-sandbox-export-bug

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@handler.go`:
- Around line 182-201: The current flow creates saveFile (os.Create) at savePath
and may leave a partial file if writing header (header, n) or streaming
(io.Copy, r.Body) fails; fix by either writing to a temporary file and renaming
on success (use os.CreateTemp -> write header and io.Copy -> close and
os.Rename(tempPath, savePath), remove temp on error) or, if keeping savePath,
ensure on any write or copy error you first close saveFile and then delete the
incomplete file with os.Remove(savePath) before returning; reference saveFile,
savePath, header, n, io.Copy and r.Body to locate the code to change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a8ba4a08-ceec-47aa-aafc-9349ffddb14a

📥 Commits

Reviewing files that changed from the base of the PR and between 504691a and e76ca8b.

📒 Files selected for processing (5)
  • frontend/src/App.tsx
  • frontend/wailsjs/runtime/package.json
  • frontend/wailsjs/runtime/runtime.d.ts
  • frontend/wailsjs/runtime/runtime.js
  • handler.go

Comment thread handler.go Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses the macOS export failure by changing the frontend upload payload and adjusting the Go save handler to avoid sandbox-incompatible temp-file creation.

Changes:

  • Converts the exported Blob to an ArrayBuffer before POSTing to /api/save.
  • Updates handleSave to validate the request body header before writing directly to the selected save path.
  • Adds Wails runtime JS/TypeScript files required by frontend imports.

Reviewed changes

Copilot reviewed 2 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
handler.go Changes save handling to validate streamed content before creating the output file.
frontend/src/App.tsx Sends an ArrayBuffer instead of a Blob for macOS WebKit compatibility.
frontend/wailsjs/runtime/runtime.js Adds Wails runtime JavaScript wrappers.
frontend/wailsjs/runtime/runtime.d.ts Adds TypeScript declarations for Wails runtime APIs.
frontend/wailsjs/runtime/package.json Adds package metadata for the Wails runtime module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread handler.go Outdated
Comment on lines 172 to 178
if expectedMime != "" && n > 0 {
actualMime := http.DetectContentType(header[:n])
if actualMime != expectedMime {
http.Error(w, "Security Error: saved file content does not match expected type", http.StatusBadRequest)
return
}
}
Comment thread handler.go Outdated
Comment on lines +180 to +184
// Validation passed. Open the target file directly.
// The app has explicit permission to write to this path granted by the native Save Dialog.
saveFile, err := os.Create(savePath)
if err != nil {
http.Error(w, "Failed to create target file: "+err.Error(), http.StatusInternalServerError)
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 5 changed files in this pull request and generated 2 comments.

Comment thread handler.go Outdated
}
if err := tmpFile.Close(); err != nil {
http.Error(w, "Failed to close temp file: "+err.Error(), http.StatusInternalServerError)
tmpFile.Close()
Comment thread handler.go
Comment on lines +221 to +228
out, err := os.Create(savePath)
if err != nil {
http.Error(w, "Failed to create final file: "+err.Error(), http.StatusInternalServerError)
return
}
defer out.Close()

if _, err := io.Copy(out, in); err != nil {
@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 17, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@handler.go`:
- Around line 221-237: When creating the fallback file with os.Create(savePath)
and writing to it (io.Copy) or syncing (out.Sync), ensure any error during write
or sync removes the partial file to avoid leaving corrupt artifacts: after
detecting errors from io.Copy or out.Sync (and before returning), close the file
handle (out.Close() if not already deferred/closed) and call os.Remove(savePath)
to delete the incomplete file; keep or adjust the existing defer out.Close() so
it doesn't conflict with explicit close-on-error, and perform Remove only on
error paths that occur after successful os.Create.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6975af41-9f34-4d83-9dcf-3b2778bf70b1

📥 Commits

Reviewing files that changed from the base of the PR and between e76ca8b and 2556bfd.

📒 Files selected for processing (1)
  • handler.go

Comment thread handler.go
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 5 changed files in this pull request and generated 2 comments.

Comment thread handler.go
}
defer in.Close()

out, err := os.Create(savePath)
Comment thread handler.go Outdated
}
if err := tmpFile.Close(); err != nil {
http.Error(w, "Failed to close temp file: "+err.Error(), http.StatusInternalServerError)
tmpFile.Close()
@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 17, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@amemya
Copy link
Copy Markdown
Owner Author

amemya commented May 17, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 5 changed files in this pull request and generated 1 comment.

Comment thread handler.go
}
defer in.Close()

out, err := os.Create(savePath)
@amemya amemya merged commit 0d755e5 into main May 18, 2026
2 checks passed
@amemya amemya deleted the hotfix/mac-sandbox-export-bug branch May 18, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Hotfix]現在(15/5/'26)時点のmainブランチでexportできない

2 participants