Skip to content

Commit 73044d1

Browse files
rkeithhillTylerLeonhardt
authored andcommitted
Fix NullRefEx bug when accessing scriptFile.ReferencedFiles (#838)
* Fix NullRefEx bug when accessing scriptFile.ReferencedFilesThis happens because the ScriptFile ctor does not initialize all itspublic props. I added initialization for the other public propsexcept for the ScriptAst prop. I don't see an empty Ast. Perhaps nullis OK for this prop?This address vscode-powershell bug https://github.com/PowerShell/vscode-powershell/issues/1675Also, for the 2.0.0 branch, we should see if we can use Array.Empty<>()for initialization. It isn't availble to net45x. :-( * Revise ScriptFile prop init to happen within ParseFileContents & add tests
1 parent 3505902 commit 73044d1

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed

src/PowerShellEditorServices/Workspace/ScriptFile.cs

+13-6
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public class ScriptFile
2626
"\n"
2727
};
2828

29-
private Token[] scriptTokens;
3029
private Version powerShellVersion;
3130

3231
#endregion
@@ -116,7 +115,8 @@ public ScriptBlockAst ScriptAst
116115
/// </summary>
117116
public Token[] ScriptTokens
118117
{
119-
get { return this.scriptTokens; }
118+
get;
119+
private set;
120120
}
121121

122122
/// <summary>
@@ -152,6 +152,7 @@ public ScriptFile(
152152
this.IsInMemory = Workspace.IsPathInMemory(filePath);
153153
this.powerShellVersion = powerShellVersion;
154154

155+
// SetFileContents() calls ParseFileContents() which initializes the rest of the properties.
155156
this.SetFileContents(textReader.ReadToEnd());
156157
}
157158

@@ -599,6 +600,8 @@ private void ParseFileContents()
599600

600601
try
601602
{
603+
Token[] scriptTokens;
604+
602605
#if PowerShellv5r2
603606
// This overload appeared with Windows 10 Update 1
604607
if (this.powerShellVersion.Major >= 5 &&
@@ -610,24 +613,26 @@ private void ParseFileContents()
610613
Parser.ParseInput(
611614
this.Contents,
612615
this.FilePath,
613-
out this.scriptTokens,
616+
out scriptTokens,
614617
out parseErrors);
615618
}
616619
else
617620
{
618621
this.ScriptAst =
619622
Parser.ParseInput(
620623
this.Contents,
621-
out this.scriptTokens,
624+
out scriptTokens,
622625
out parseErrors);
623626
}
624627
#else
625628
this.ScriptAst =
626629
Parser.ParseInput(
627630
this.Contents,
628-
out this.scriptTokens,
631+
out scriptTokens,
629632
out parseErrors);
630633
#endif
634+
635+
this.ScriptTokens = scriptTokens;
631636
}
632637
catch (RuntimeException ex)
633638
{
@@ -638,7 +643,7 @@ private void ParseFileContents()
638643
ex.Message);
639644

640645
parseErrors = new[] { parseError };
641-
this.scriptTokens = new Token[0];
646+
this.ScriptTokens = new Token[0];
642647
this.ScriptAst = null;
643648
}
644649

@@ -654,6 +659,8 @@ private void ParseFileContents()
654659
// users should save the file.
655660
if (IsUntitledPath(this.FilePath))
656661
{
662+
// Need to initialize the ReferencedFiles property to an empty array.
663+
this.ReferencedFiles = new string[0];
657664
return;
658665
}
659666

test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs

+51-4
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,10 @@ public void CanAppendToEndOfFile()
164164
public void FindsDotSourcedFiles()
165165
{
166166
string exampleScriptContents =
167-
@". .\athing.ps1"+"\r\n"+
168-
@". .\somefile.ps1"+"\r\n" +
169-
@". .\somefile.ps1"+"\r\n" +
170-
@"Do-Stuff $uri"+"\r\n" +
167+
@". .\athing.ps1" + "\r\n" +
168+
@". .\somefile.ps1" + "\r\n" +
169+
@". .\somefile.ps1" + "\r\n" +
170+
@"Do-Stuff $uri" + "\r\n" +
171171
@". simpleps.ps1";
172172

173173
using (StringReader stringReader = new StringReader(exampleScriptContents))
@@ -532,4 +532,51 @@ private void AssertNewPosition(
532532
Assert.Equal(expectedColumn, newPosition.Column);
533533
}
534534
}
535+
536+
public class ScriptFileConstructorTests
537+
{
538+
private static readonly Version PowerShellVersion = new Version("5.0");
539+
540+
[Fact]
541+
public void PropertiesInitializedCorrectlyForFile()
542+
{
543+
var path = "TestFile.ps1";
544+
var scriptFile = ScriptFileChangeTests.CreateScriptFile("");
545+
546+
Assert.Equal(path, scriptFile.FilePath);
547+
Assert.Equal(path, scriptFile.ClientFilePath);
548+
Assert.True(scriptFile.IsAnalysisEnabled);
549+
Assert.False(scriptFile.IsInMemory);
550+
Assert.Empty(scriptFile.ReferencedFiles);
551+
Assert.Empty(scriptFile.SyntaxMarkers);
552+
Assert.Single(scriptFile.ScriptTokens);
553+
Assert.Single(scriptFile.FileLines);
554+
}
555+
556+
[Fact]
557+
public void PropertiesInitializedCorrectlyForUntitled()
558+
{
559+
var path = "untitled:untitled-1";
560+
561+
// 3 lines and 10 tokens in this script.
562+
var script = @"function foo() {
563+
'foo'
564+
}";
565+
566+
using (StringReader stringReader = new StringReader(script))
567+
{
568+
// Create an in-memory file from the StringReader
569+
var scriptFile = new ScriptFile(path, path, stringReader, PowerShellVersion);
570+
571+
Assert.Equal(path, scriptFile.FilePath);
572+
Assert.Equal(path, scriptFile.ClientFilePath);
573+
Assert.True(scriptFile.IsAnalysisEnabled);
574+
Assert.True(scriptFile.IsInMemory);
575+
Assert.Empty(scriptFile.ReferencedFiles);
576+
Assert.Empty(scriptFile.SyntaxMarkers);
577+
Assert.Equal(10, scriptFile.ScriptTokens.Length);
578+
Assert.Equal(3, scriptFile.FileLines.Count);
579+
}
580+
}
581+
}
535582
}

0 commit comments

Comments
 (0)