Skip to content

Commit 5afa456

Browse files
authored
Replace bad StringReader usage with String.Split() (#784)
* Replace bad StringReader usage with String.Split(). * Add test cases to include trailing newline and no trailing newline.
1 parent f962e0d commit 5afa456

File tree

2 files changed

+43
-42
lines changed

2 files changed

+43
-42
lines changed

src/PowerShellEditorServices/Workspace/ScriptFile.cs

+8-22
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public class ScriptFile
2020
{
2121
#region Private Fields
2222

23+
private static readonly string[] s_newlines = new []
24+
{
25+
"\r\n",
26+
"\n"
27+
};
28+
2329
private Token[] scriptTokens;
2430
private Version powerShellVersion;
2531

@@ -167,8 +173,8 @@ public ScriptFile(
167173
new StringReader(initialBuffer),
168174
powerShellVersion)
169175
{
170-
171176
}
177+
172178
/// <summary>
173179
/// Creates a new ScriptFile instance with the specified filepath.
174180
/// </summary>
@@ -185,7 +191,6 @@ public ScriptFile(
185191
File.ReadAllText(filePath),
186192
powerShellVersion)
187193
{
188-
189194
}
190195

191196
#endregion
@@ -215,26 +220,7 @@ internal static List<string> GetLinesInternal(string text)
215220
throw new ArgumentNullException(nameof(text));
216221
}
217222

218-
// ReadLine returns null immediately for empty string, so special case it.
219-
if (text.Length == 0)
220-
{
221-
return new List<string> {string.Empty};
222-
}
223-
224-
using (var reader = new StringReader(text))
225-
{
226-
// 50 is a rough guess for typical average line length, this saves some list
227-
// resizes in the common case and does not hurt meaningfully if we're wrong.
228-
var list = new List<string>(text.Length / 50);
229-
string line;
230-
231-
while ((line = reader.ReadLine()) != null)
232-
{
233-
list.Add(line);
234-
}
235-
236-
return list;
237-
}
223+
return new List<string>(text.Split(s_newlines, StringSplitOptions.None));
238224
}
239225

240226
/// <summary>

test/PowerShellEditorServices.Test/Session/ScriptFileTests.cs

+35-20
Original file line numberDiff line numberDiff line change
@@ -255,26 +255,35 @@ private void AssertFileChange(
255255

256256
public class ScriptFileGetLinesTests
257257
{
258-
private ScriptFile scriptFile;
258+
private const string TestString_NoTrailingNewline = "Line One\r\nLine Two\r\nLine Three\r\nLine Four\r\nLine Five";
259+
260+
private const string TestString_TrailingNewline = TestString_NoTrailingNewline + "\r\n";
261+
262+
private static readonly string[] s_newLines = new string[] { "\r\n" };
263+
264+
private static readonly string[] s_testStringLines_noTrailingNewline = TestString_NoTrailingNewline.Split(s_newLines, StringSplitOptions.None);
265+
266+
private static readonly string[] s_testStringLines_trailingNewline = TestString_TrailingNewline.Split(s_newLines, StringSplitOptions.None);
267+
268+
private ScriptFile _scriptFile_trailingNewline;
269+
270+
private ScriptFile _scriptFile_noTrailingNewline;
259271

260-
private const string TestString = "Line One\r\nLine Two\r\nLine Three\r\nLine Four\r\nLine Five";
261-
private readonly string[] TestStringLines =
262-
TestString.Split(
263-
new string[] { "\r\n" },
264-
StringSplitOptions.None);
265272

266273
public ScriptFileGetLinesTests()
267274
{
268-
this.scriptFile =
269-
ScriptFileChangeTests.CreateScriptFile(
270-
"Line One\r\nLine Two\r\nLine Three\r\nLine Four\r\nLine Five\r\n");
275+
_scriptFile_noTrailingNewline = ScriptFileChangeTests.CreateScriptFile(
276+
TestString_NoTrailingNewline);
277+
278+
_scriptFile_trailingNewline = ScriptFileChangeTests.CreateScriptFile(
279+
TestString_TrailingNewline);
271280
}
272281

273282
[Fact]
274283
public void CanGetWholeLine()
275284
{
276285
string[] lines =
277-
this.scriptFile.GetLinesInRange(
286+
_scriptFile_noTrailingNewline.GetLinesInRange(
278287
new BufferRange(5, 1, 5, 10));
279288

280289
Assert.Equal(1, lines.Length);
@@ -285,17 +294,17 @@ public void CanGetWholeLine()
285294
public void CanGetMultipleWholeLines()
286295
{
287296
string[] lines =
288-
this.scriptFile.GetLinesInRange(
297+
_scriptFile_noTrailingNewline.GetLinesInRange(
289298
new BufferRange(2, 1, 4, 10));
290299

291-
Assert.Equal(TestStringLines.Skip(1).Take(3), lines);
300+
Assert.Equal(s_testStringLines_noTrailingNewline.Skip(1).Take(3), lines);
292301
}
293302

294303
[Fact]
295304
public void CanGetSubstringInSingleLine()
296305
{
297306
string[] lines =
298-
this.scriptFile.GetLinesInRange(
307+
_scriptFile_noTrailingNewline.GetLinesInRange(
299308
new BufferRange(4, 3, 4, 8));
300309

301310
Assert.Equal(1, lines.Length);
@@ -306,7 +315,7 @@ public void CanGetSubstringInSingleLine()
306315
public void CanGetEmptySubstringRange()
307316
{
308317
string[] lines =
309-
this.scriptFile.GetLinesInRange(
318+
_scriptFile_noTrailingNewline.GetLinesInRange(
310319
new BufferRange(4, 3, 4, 3));
311320

312321
Assert.Equal(1, lines.Length);
@@ -324,7 +333,7 @@ public void CanGetSubstringInMultipleLines()
324333
};
325334

326335
string[] lines =
327-
this.scriptFile.GetLinesInRange(
336+
_scriptFile_noTrailingNewline.GetLinesInRange(
328337
new BufferRange(2, 6, 4, 9));
329338

330339
Assert.Equal(expectedLines, lines);
@@ -341,23 +350,29 @@ public void CanGetRangeAtLineBoundaries()
341350
};
342351

343352
string[] lines =
344-
this.scriptFile.GetLinesInRange(
353+
_scriptFile_noTrailingNewline.GetLinesInRange(
345354
new BufferRange(2, 9, 4, 1));
346355

347356
Assert.Equal(expectedLines, lines);
348357
}
349358

350359
[Fact]
351-
public void CanSplitLines()
360+
public void CanSplitLines_NoTrailingNewline()
361+
{
362+
Assert.Equal(s_testStringLines_noTrailingNewline, _scriptFile_noTrailingNewline.FileLines);
363+
}
364+
365+
[Fact]
366+
public void CanSplitLines_TrailingNewline()
352367
{
353-
Assert.Equal(TestStringLines, scriptFile.FileLines);
368+
Assert.Equal(s_testStringLines_trailingNewline, _scriptFile_trailingNewline.FileLines);
354369
}
355370

356371
[Fact]
357372
public void CanGetSameLinesWithUnixLineBreaks()
358373
{
359-
var unixFile = ScriptFileChangeTests.CreateScriptFile(TestString.Replace("\r\n", "\n"));
360-
Assert.Equal(scriptFile.FileLines, unixFile.FileLines);
374+
var unixFile = ScriptFileChangeTests.CreateScriptFile(TestString_NoTrailingNewline.Replace("\r\n", "\n"));
375+
Assert.Equal(_scriptFile_noTrailingNewline.FileLines, unixFile.FileLines);
361376
}
362377

363378
[Fact]

0 commit comments

Comments
 (0)