-
Notifications
You must be signed in to change notification settings - Fork 645
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR @Charliekenney23!
I would still insist on persisting the tmp dir path. Otherwise, we would end up creating new directories unnecessarily each time the user saves a file or runs code coverage.
src/goBuild.ts
Outdated
@@ -70,7 +70,7 @@ export function goBuild(fileUri: vscode.Uri, goConfig: vscode.WorkspaceConfigura | |||
} | |||
|
|||
const buildEnv = Object.assign({}, getToolsEnvVars()); | |||
const tmpPath = path.normalize(path.join(os.tmpdir(), 'go-code-check.' + getUserNameHash())); | |||
const tmpPath = getTempFile('go-code-check.' + getUserNameHash()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/util.ts
Outdated
let dir: string | undefined; | ||
return (): string => { | ||
if (!dir) { | ||
dir = fs.mkdtempSync(os.tmpdir() + '/vscode-go'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use path.sep
to create the path here instead of /
@ramya-rao-a I've updated the code to persist the temp directory path between vscode sessions. Please let me know if there's anything else that needs to be updated! |
ff41b84
to
1664a15
Compare
src/debugAdapter/goDebug.ts
Outdated
@@ -12,6 +12,7 @@ import { basename, dirname, extname } from 'path'; | |||
import { spawn, ChildProcess, execSync, spawnSync, execFile } from 'child_process'; | |||
import { Client, RPCConnection } from 'json-rpc2'; | |||
import { parseEnvFile, getBinPathWithPreferredGopath, resolveHomeDir, getInferredGopath, getCurrentGoWorkspaceFromGOPATH, envPath, fixDriveCasingInWindows } from '../goPath'; | |||
import { TempFileProvider } from '../util'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The debug adapter runs in a separate process and does not have access to anything from the vscode
module. Therefore a dependency here on util
will fail as util imports from vscode
.
The tmp dir is used in the debug adapter to create the trace files. Since this is not done by default and the user sets explicitly to debug an issue with the debugger, I believe we are ok with creating a new file under os.tmpdir()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/util.ts
Outdated
private constructor() {} | ||
private static _instance: TempFileProvider; | ||
|
||
static get instance() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not make this a static class? Then, we can skip the instance()
method here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good point. I'll make this a static class 😃
src/util.ts
Outdated
return TempFileProvider._instance; | ||
} | ||
|
||
private store: vscode.Memento; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's call this the globalState
so that when code reading we know exactly where the data is stored
src/util.ts
Outdated
this.store = store; | ||
} | ||
|
||
get dir(): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since getFilePath
is the only place this is used, can we merge this code into getFilePath
?
1664a15
to
ec11985
Compare
I've updated the code with the suggested changes 😃 |
src/goMain.ts
Outdated
@@ -83,6 +83,7 @@ export function activate(ctx: vscode.ExtensionContext): void { | |||
}); | |||
} | |||
ctx.globalState.update('goroot', currentGoroot); | |||
TempFileProvider.registerStore(ctx.globalState); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this to the very top. Just to make sure that the globalState is available in the TempFileProvider right from the start
src/util.ts
Outdated
* returns path to temp file with name | ||
*/ | ||
static getFilePath(name: string): string { | ||
let tempDir = TempFileProvider.globalState.get<string>('tempDir'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One corner case is that getFilePath
gets called when the globalState is not yet set. This may not happen now, but when the code that registers the store gets moved around in the future, it can happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a comment to above TempFileProvider.registerStore must be called before this
.
One work around could be creating a new temp dir if globalState is undefined (and storing it locally on the object). Thoughts?
fc2cdfd
to
10757de
Compare
10757de
to
5472067
Compare
Many systems clean the tmp directory every boot or on other schedules or even use a RAM based file system that is not persisted to disk. Will the persisted tmpdir in this PR work correctly if the tmpdir disappears? |
Usually, mkdtemp and friends are used so that the library safely creates and picks a directory and then you use whatever dir you got. I haven't seen it used so that you recreate one with the same name you got earlier. It may be ok, but I'm not sure. Now, you may call me overly paranoid, but what about the following attack scenario: Alice uses the vscode extension, which correctly makes a tmpdir /tmp/vscode.hMF460T1CB and it is persisted in vscode's config. Bob on the same machine monitors /tmp and sees Alice's tmpdir. It is inaccessible to him, so he can't do anything about it. However, Bob knows that /tmp is wiped on boot, and he crafts a cron job (a scheduled program execution) that as soon as possible (when the dir disappears) creates a directory with Alice's tmpdir name and sets the permissions to be accessible by Alice (e.g., world readable and writable) and performs the symlink attack I suggested earlier, e.g., Personally I'd err on the side of caution and not persist the tmpdir name, but recreate it every time and remove it when done with. If the concern is that junk may be left behind, we could remove all /tmp/vscode.* owned by the user at some convenient time, perhaps before creating a new tmpdir. If we want a persistent dir, then tmpdir might not be the right thing and we should put it under the users home dir or maybe the workspace dir. Sorry for trying to figure out how to break things, I've my security goggles on this week :-) |
So I think the only benefit of persisting the temp directory path is to limit VSCode from polluting the Thoughts, @ramya-rao-a? |
Those are some great points @antong, thanks for bringing them up. I have pushed a change to not re-use a persisted directory if it does not exist. That should take care of most of your concerns @Charliekenney23 The comment is helpful, but I added a check regardless. Do take a look.
Yes, lets do this if @antong finds any other risk with the change I made :) |
What if the directory does exist and is writable, but is owned by somebody else (was autoremoved, but recreated by evil Bob)? |
good point, lets go with creating a tmpdir on extension activation (which happens for each VS Code session), recreating it if it doesnt exist during the session and removing it when extension is deactivated (which happens when VS Code window is closed) |
On a side note: @antong you are awesome |
Agreed! I've just updated the code. |
Just a note: There will be some edge cases where the tmp dir will not be deleted (for instance, when the user force quits vscode, the extension does not have time to call In effort to minimize these stray directories, I'm only creating the temp directory as needed (when the |
@Charliekenney23 I've refactored the code a bit to avoid using classes as the rest of the util.ts file doesn't use any. This is just to be consistent with the coding style in the file and to make it easier for future maintenance. Can you take a look? |
@ramya-rao-a LGTM! |
Closes #1905.
This closely mirrors the official TypeScript extension's implementation, which does not persist the directory path for reuse between activations.
@ramya-rao-a, making the directory path persistent is pretty hacky and not the convention for any of the official extensions I've seen, so I've left it out (let me know your thoughts on this).