Skip to content

Commit b61bdb9

Browse files
authored
Fix SoundPlayer handling of partial reads on streams (#82612)
SoundPlayer assumes that a Read on a stream will return everything asked for, and that's not the case.
1 parent 8162ac9 commit b61bdb9

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,20 @@ private void LoadStream(bool loadSync)
310310
int streamLen = (int)_stream.Length;
311311
_currentPos = 0;
312312
_streamData = new byte[streamLen];
313-
_stream.Read(_streamData, 0, streamLen);
313+
#if NET7_0_OR_GREATER
314+
_stream.ReadExactly(_streamData);
315+
#else
316+
int totalRead = 0;
317+
while (totalRead < streamLen)
318+
{
319+
int bytesRead = _stream.Read(_streamData, totalRead, streamLen - totalRead);
320+
if (bytesRead <= 0)
321+
{
322+
throw new EndOfStreamException();
323+
}
324+
totalRead += bytesRead;
325+
}
326+
#endif
314327
IsLoadCompleted = true;
315328
OnLoadCompleted(new AsyncCompletedEventArgs(null, false, null));
316329
}

src/libraries/System.Windows.Extensions/tests/System/Media/SoundPlayerTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,22 @@ public void PlayLooping_NullStream_Success()
293293
player.PlayLooping();
294294
}
295295

296+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsSoundPlaySupported))]
297+
[MemberData(nameof(Play_String_TestData))]
298+
[OuterLoop]
299+
public void PlaySync_TrickledData_Success(string sourceLocation)
300+
{
301+
using var player = new SoundPlayer();
302+
player.Stream = new TrickleStream(File.ReadAllBytes(sourceLocation.Replace("file://", "")));
303+
player.PlaySync();
304+
}
305+
306+
private sealed class TrickleStream : MemoryStream
307+
{
308+
public TrickleStream(byte[] bytes) : base(bytes) { }
309+
public override int Read(byte[] buffer, int offset, int count) => base.Read(buffer, offset, Math.Min(count, 1));
310+
}
311+
296312
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsSoundPlaySupported))]
297313
[OuterLoop]
298314
public void PlaySync_NullStream_Success()

0 commit comments

Comments
 (0)