Skip to content

Commit 1c7b30f

Browse files
committed
fix(browse): restrict /api/browse to root; allow full access for file picker dialogs
1 parent a51a048 commit 1c7b30f

3 files changed

Lines changed: 38 additions & 1 deletion

File tree

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
大きなコードベース(Linux カーネル、OpenSSL、curl など)を読む際に、検索結果をグラフに積み上げながら構造を把握していくことを想定しています。
88

9+
ビルドシステムが複雑で `compile_commands.json` を生成しにくいプロジェクトや、clangd のセットアップが難しい環境でも、インクルード依存グラフや定義ジャンプが動作します。
10+
911
> **ローカル専用ツールです**
1012
> 自分の PC で起動して、同じ PC のブラウザからアクセスして使います。
1113
> サーバーへのデプロイや、他の人が外部からアクセスできる環境での使用は想定していません。
@@ -128,6 +130,7 @@ static 変数・関数呼び出しはテキストパターンに基づくヒュ
128130
| [Go](https://golang.org/) 1.25 以上 || ソースからビルドする場合のみ。バイナリ配布版は不要 |
129131
| [ripgrep](https://github.com/BurntSushi/ripgrep) || `rg` コマンドが PATH にあること |
130132
| [GNU Global](https://www.gnu.org/software/global/) || **なくても動作します。** `gtags` / `global` コマンドが PATH にあると定義ジャンプ・ホバー・Callers の精度が向上 |
133+
| [Universal Ctags](https://github.com/universal-ctags/ctags) || **なくても動作します。** `tags` ファイルを生成しておくと定義ジャンプの精度が向上し、定数・マクロのハイライトが有効になる |
131134

132135
---
133136

@@ -223,6 +226,27 @@ grepnavi/
223226

224227
---
225228

229+
## Universal Ctags(オプション)
230+
231+
[Universal Ctags](https://github.com/universal-ctags/ctags)`tags` ファイルを生成しておくと、定義ジャンプの精度が向上し、定数・マクロのハイライトが有効になります。
232+
233+
### インストール(Windows)
234+
235+
```bash
236+
scoop install universal-ctags
237+
```
238+
239+
### 使い方
240+
241+
1. grepnavi を起動し、プロジェクトルートを開く
242+
2. エディタのファイルヘッダ右端に表示される **定義ジャンプエンジン** ラベルをクリック
243+
3. ポップオーバーで「インデックス → 生成」を実行
244+
4. 以降、定義ジャンプ(Ctrl+クリック / F12)・定数マクロのハイライトが有効になる
245+
246+
インデックスは `tags` ファイルとしてプロジェクトルートに保存されます。ファイルを追加・変更した後は「更新」で再生成してください。
247+
248+
---
249+
226250
## 使い方
227251

228252
### 基本的な流れ
@@ -402,7 +426,7 @@ grepnavi/
402426
│ ├── search.js # 検索・フィルタ・結果表示
403427
│ ├── graph.js # グラフ/ツリー操作・D3.js・詳細パネル・D&D
404428
│ ├── editor.js # Monaco エディタ・fzf・ナビ履歴・行メモ・#ifdef
405-
│ ├── memo-list.js # メモリストパネル(行・範囲メモ一覧・グループ管理)
429+
│ ├── memo-list.js # メモリストパネル(行・範囲メモ一覧・グループ管理)
406430
│ ├── editor-c.js # C/C++ 固有拡張(static変数・関数呼び出し・定数のハイライト、ローカル変数ホバー抑制)
407431
│ ├── gtags.js # GNU Global UI(エンジン選択・インデックス管理)
408432
│ ├── include-graph.js # C インクルード依存グラフ(D3.js)

api/handlers_fileops.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ func (h *Handler) handleBrowse(w http.ResponseWriter, r *http.Request) {
245245
dir := q.Get("path")
246246
ext := q.Get("ext") // e.g. ".json"
247247

248+
pick := q.Get("pick") == "1" // ルート選択ダイアログからの呼び出し
249+
explicitPath := dir != ""
248250
if dir == "" {
249251
if exe, err := os.Executable(); err == nil {
250252
dir = filepath.Dir(exe)
@@ -254,6 +256,16 @@ func (h *Handler) handleBrowse(w http.ResponseWriter, r *http.Request) {
254256
}
255257
dir = filepath.Clean(dir)
256258

259+
if explicitPath && !pick {
260+
h.mu.RLock()
261+
root := filepath.Clean(h.root)
262+
h.mu.RUnlock()
263+
if !strings.HasPrefix(dir+string(filepath.Separator), root+string(filepath.Separator)) {
264+
jsonErr(w, "path outside root", http.StatusForbidden)
265+
return
266+
}
267+
}
268+
257269
entries, err := os.ReadDir(dir)
258270
if err != nil {
259271
jsonErr(w, err.Error(), http.StatusBadRequest)

static/js/filebrowser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ async function fbNavigate(dir, pushHistory = true, focusName = null) {
9595
const ext = (_fbMode === 'open-file') ? '' : '.json';
9696
const params = new URLSearchParams({ ext });
9797
if(dir) params.set('path', dir);
98+
if(['dir', 'open', 'save', 'open-file'].includes(_fbMode)) params.set('pick', '1');
9899
const res = await fetch('/api/browse?' + params).catch(() => null);
99100
if(!res || !res.ok) { st('ディレクトリを開けませんでした'); return; }
100101
const data = await res.json();

0 commit comments

Comments
 (0)