Skip to content

Commit 637295e

Browse files
committed
ConvertFrom-Json: Ignore comments inside array literals (#14553)
1 parent 37a0e33 commit 637295e

File tree

2 files changed

+70
-52
lines changed

2 files changed

+70
-52
lines changed

src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using System.Management.Automation.Language;
1111
using System.Numerics;
1212
using System.Reflection;
13-
using System.Text.RegularExpressions;
1413
using System.Threading;
1514

1615
using Newtonsoft.Json;
@@ -289,11 +288,11 @@ private static PSObject PopulateFromJDictionary(JObject entries, DuplicateMember
289288
return null;
290289
}
291290

292-
// Array
293291
switch (entry.Value)
294292
{
295293
case JArray list:
296294
{
295+
// Array
297296
var listResult = PopulateFromJArray(list, out error);
298297
if (error != null)
299298
{
@@ -331,47 +330,41 @@ private static PSObject PopulateFromJDictionary(JObject entries, DuplicateMember
331330
// This function is a clone of PopulateFromList using JArray as input.
332331
private static ICollection<object> PopulateFromJArray(JArray list, out ErrorRecord error)
333332
{
334-
error = null;
335333
var result = new object[list.Count];
334+
var i = 0;
336335

337-
for (var index = 0; index < list.Count; index++)
336+
foreach (var element in list)
338337
{
339-
var element = list[index];
340338
switch (element)
341339
{
342340
case JArray subList:
341+
// Array
342+
result[i++] = PopulateFromJArray(subList, out error);
343+
if (error != null)
343344
{
344-
// Array
345-
var listResult = PopulateFromJArray(subList, out error);
346-
if (error != null)
347-
{
348-
return null;
349-
}
350-
351-
result[index] = listResult;
352-
break;
345+
return null;
353346
}
347+
break;
354348
case JObject dic:
349+
// Dictionary
350+
result[i++] = PopulateFromJDictionary(dic, new DuplicateMemberHashSet(dic.Count), out error);
351+
if (error != null)
355352
{
356-
// Dictionary
357-
var dicResult = PopulateFromJDictionary(dic, new DuplicateMemberHashSet(dic.Count), out error);
358-
if (error != null)
359-
{
360-
return null;
361-
}
362-
363-
result[index] = dicResult;
364-
break;
353+
return null;
365354
}
355+
break;
366356
case JValue value:
357+
if (value.Type != JTokenType.Comment)
367358
{
368-
result[index] = value.Value;
369-
break;
359+
result[i++] = value.Value;
370360
}
361+
break;
371362
}
372363
}
373364

374-
return result;
365+
error = null;
366+
// In the common case of not having any comments, return the original array, otherwise create a sliced copy.
367+
return i == list.Count ? result : result[..i];
375368
}
376369

377370
// This function is a clone of PopulateFromDictionary using JObject as an input.
@@ -434,48 +427,41 @@ private static Hashtable PopulateHashTableFromJDictionary(JObject entries, out E
434427
// This function is a clone of PopulateFromList using JArray as input.
435428
private static ICollection<object> PopulateHashTableFromJArray(JArray list, out ErrorRecord error)
436429
{
437-
error = null;
438430
var result = new object[list.Count];
431+
var i = 0;
439432

440-
for (var index = 0; index < list.Count; index++)
433+
foreach (var element in list)
441434
{
442-
var element = list[index];
443-
444435
switch (element)
445436
{
446-
case JArray array:
437+
case JArray subList:
438+
// Array
439+
result[i++] = PopulateHashTableFromJArray(subList, out error);
440+
if (error != null)
447441
{
448-
// Array
449-
var listResult = PopulateHashTableFromJArray(array, out error);
450-
if (error != null)
451-
{
452-
return null;
453-
}
454-
455-
result[index] = listResult;
456-
break;
442+
return null;
457443
}
444+
break;
458445
case JObject dic:
446+
// Dictionary
447+
result[i++] = PopulateHashTableFromJDictionary(dic, out error);
448+
if (error != null)
459449
{
460-
// Dictionary
461-
var dicResult = PopulateHashTableFromJDictionary(dic, out error);
462-
if (error != null)
463-
{
464-
return null;
465-
}
466-
467-
result[index] = dicResult;
468-
break;
450+
return null;
469451
}
452+
break;
470453
case JValue value:
454+
if (value.Type != JTokenType.Comment)
471455
{
472-
result[index] = value.Value;
473-
break;
456+
result[i++] = value.Value;
474457
}
458+
break;
475459
}
476460
}
477461

478-
return result;
462+
error = null;
463+
// In the common case of not having any comments, return the original array, otherwise create a sliced copy.
464+
return i == list.Count ? result : result[..i];
479465
}
480466

481467
#endregion ConvertFromJson

test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,38 @@ c 3
350350
$json | Should -BeOfType ([string])
351351
$json | Should -Be $Value.Substring(1, $Value.Length - 2)
352352
}
353+
354+
It 'Ignores comments in arrays' -TestCase $testCasesWithAndWithoutAsHashtableSwitch {
355+
param($AsHashtable)
356+
357+
# https://github.com/powerShell/powerShell/issues/14553
358+
'[
359+
// foo
360+
100,
361+
/* bar */
362+
200
363+
]' | ConvertFrom-Json -AsHashtable:$AsHashtable | Should -Be @(100, 200)
364+
}
365+
366+
It 'Ignores comments in dictionaries' -TestCase $testCasesWithAndWithoutAsHashtableSwitch {
367+
param($AsHashtable)
368+
369+
$json = '{
370+
// foo
371+
"a": 100,
372+
/* bar */
373+
"b": 200
374+
}' | ConvertFrom-Json -AsHashtable:$AsHashtable
375+
376+
if ($AsHashtable) {
377+
$json.Keys | Should -Be @("a", "b")
378+
} else {
379+
$json.psobject.Properties | Should -HaveCount 2
380+
}
381+
382+
$json.a | Should -Be 100
383+
$json.b | Should -Be 200
384+
}
353385
}
354386

355387
Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" {

0 commit comments

Comments
 (0)