Skip to content

Commit 40d718b

Browse files
authored
Do not set breakpoint on non-PowerShell files (#575)
* Do not attempt to set breakpoints for non-PS script files * In some cases, VSCode is passing an empty string for cwd * Move untitled: test into a static method inScriptFile
1 parent 23fa4bf commit 40d718b

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

+38-8
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ protected Task LaunchScript(RequestContext<object> requestContext)
8787
// Is this an untitled script?
8888
Task launchTask = null;
8989

90-
if (this.scriptToLaunch.StartsWith("untitled:"))
90+
if (ScriptFile.IsUntitledPath(this.scriptToLaunch))
9191
{
9292
ScriptFile untitledScript =
9393
this.editorSession.Workspace.GetFile(
@@ -259,12 +259,12 @@ protected async Task HandleLaunchRequest(
259259

260260
// When debugging an "untitled" (unsaved) file - the working dir can't be derived
261261
// from the Script path. OTOH, if the launch params specifies a Cwd, use it.
262-
if (workingDir.StartsWith("untitled:") && string.IsNullOrEmpty(launchParams.Cwd))
262+
if (ScriptFile.IsUntitledPath(workingDir) && string.IsNullOrEmpty(launchParams.Cwd))
263263
{
264264
workingDir = null;
265265
}
266266

267-
if (workingDir != null)
267+
if (!string.IsNullOrEmpty(workingDir))
268268
{
269269
workingDir = PowerShellContext.UnescapePath(workingDir);
270270
try
@@ -282,7 +282,7 @@ protected async Task HandleLaunchRequest(
282282
}
283283
}
284284

285-
if (workingDir == null)
285+
if (string.IsNullOrEmpty(workingDir))
286286
{
287287
#if CoreCLR
288288
workingDir = AppContext.BaseDirectory;
@@ -490,7 +490,12 @@ protected async Task HandleSetBreakpointsRequest(
490490
// VSCode sends breakpoint requests with the original filename that doesn't exist anymore.
491491
try
492492
{
493-
scriptFile = editorSession.Workspace.GetFile(setBreakpointsParams.Source.Path);
493+
// When you set a breakpoint in the right pane of a Git diff window on a PS1 file,
494+
// the Source.Path comes through as Untitled-X.
495+
if (!ScriptFile.IsUntitledPath(setBreakpointsParams.Source.Path))
496+
{
497+
scriptFile = editorSession.Workspace.GetFile(setBreakpointsParams.Source.Path);
498+
}
494499
}
495500
catch (Exception e) when (e is FileNotFoundException || e is DirectoryNotFoundException)
496501
{
@@ -510,9 +515,34 @@ await requestContext.SendResult(
510515
Breakpoints = srcBreakpoints.ToArray()
511516
});
512517

513-
return;
514-
}
518+
return;
519+
}
520+
521+
// Verify source file is a PowerShell script file.
522+
string fileExtension = Path.GetExtension(scriptFile?.FilePath ?? "")?.ToLower();
523+
if (string.IsNullOrEmpty(fileExtension) || ((fileExtension != ".ps1") && (fileExtension != ".psm1")))
524+
{
525+
Logger.Write(
526+
LogLevel.Warning,
527+
$"Attempted to set breakpoints on a non-PowerShell file: {setBreakpointsParams.Source.Path}");
528+
529+
string message = this.noDebug ? string.Empty : "Source is not a PowerShell script, breakpoint not set.";
530+
531+
var srcBreakpoints = setBreakpointsParams.Breakpoints
532+
.Select(srcBkpt => Protocol.DebugAdapter.Breakpoint.Create(
533+
srcBkpt, setBreakpointsParams.Source.Path, message, verified: this.noDebug));
534+
535+
// Return non-verified breakpoint message.
536+
await requestContext.SendResult(
537+
new SetBreakpointsResponseBody
538+
{
539+
Breakpoints = srcBreakpoints.ToArray()
540+
});
541+
542+
return;
543+
}
515544

545+
// At this point, the source file has been verified as a PowerShell script.
516546
var breakpointDetails = new BreakpointDetails[setBreakpointsParams.Breakpoints.Length];
517547
for (int i = 0; i < breakpointDetails.Length; i++)
518548
{
@@ -541,7 +571,7 @@ await editorSession.DebugService.SetLineBreakpoints(
541571
catch (Exception e)
542572
{
543573
// Log whatever the error is
544-
Logger.WriteException("Caught error while setting breakpoints in SetBreakpoints handler", e);
574+
Logger.WriteException($"Caught error while setting breakpoints in SetBreakpoints handler for file {scriptFile?.FilePath}", e);
545575
}
546576
finally
547577
{

src/PowerShellEditorServices/Workspace/ScriptFile.cs

+13
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,19 @@ public static IEnumerable<string> GetLines(string text)
207207
return text.Split('\n').Select(line => line.TrimEnd('\r'));
208208
}
209209

210+
/// <summary>
211+
/// Deterines whether the supplied path indicates the file is an "untitled:Unitled-X"
212+
/// which has not been saved to file.
213+
/// </summary>
214+
/// <param name="path">The path to check.</param>
215+
/// <returns>True if the path is an untitled file, false otherwise.</returns>
216+
public static bool IsUntitledPath(string path)
217+
{
218+
Validate.IsNotNull(nameof(path), path);
219+
220+
return path.ToLower().StartsWith("untitled:");
221+
}
222+
210223
/// <summary>
211224
/// Gets a line from the file's contents.
212225
/// </summary>

0 commit comments

Comments
 (0)