internal ArraySegment <byte> ConvertNativeBuffer(WebSocketProtocolComponent.Action action, Interop.WebSocket.Buffer buffer, WebSocketProtocolComponent.BufferType bufferType) { ThrowIfDisposed(); IntPtr bufferData; uint bufferLength; UnwrapWebSocketBuffer(buffer, bufferType, out bufferData, out bufferLength); if (bufferData == IntPtr.Zero) { return(ArraySegment <byte> .Empty); } if (this.IsNativeBuffer(bufferData, bufferLength)) { return(new ArraySegment <byte>(_internalBuffer.Array, this.GetOffset(bufferData), (int)bufferLength)); } Debug.Assert(false, "'buffer' MUST reference a memory segment within the pinned InternalBuffer."); // Indicates a violation in the contract with native Websocket.dll and could indicate // memory corruption because the internal buffer is shared between managed and native code throw new AccessViolationException(); }
internal void ConvertCloseBuffer(WebSocketProtocolComponent.Action action, Interop.WebSocket.Buffer buffer, out WebSocketCloseStatus closeStatus, out string reason) { ThrowIfDisposed(); IntPtr bufferData; uint bufferLength; closeStatus = (WebSocketCloseStatus)buffer.CloseStatus.CloseStatus; UnwrapWebSocketBuffer(buffer, WebSocketProtocolComponent.BufferType.Close, out bufferData, out bufferLength); if (bufferData == IntPtr.Zero) { reason = null; } else { ArraySegment <byte> reasonBlob; if (this.IsNativeBuffer(bufferData, bufferLength)) { reasonBlob = new ArraySegment <byte>(_internalBuffer.Array, this.GetOffset(bufferData), (int)bufferLength); } else { Debug.Assert(false, "'buffer' MUST reference a memory segment within the pinned InternalBuffer."); // Indicates a violation in the contract with native Websocket.dll and could indicate // memory corruption because the internal buffer is shared between managed and native code throw new AccessViolationException(); } // No need to wrap DecoderFallbackException for invalid UTF8 chacters, because // Encoding.UTF8 will not throw but replace invalid characters instead. reason = Encoding.UTF8.GetString(reasonBlob.Array, reasonBlob.Offset, reasonBlob.Count); } }
internal void ValidateNativeBuffers(WebSocketProtocolComponent.Action action, WebSocketProtocolComponent.BufferType bufferType, Interop.WebSocket.Buffer[] dataBuffers, uint dataBufferCount) { Debug.Assert(dataBufferCount <= (uint)int.MaxValue, "'dataBufferCount' MUST NOT be bigger than Int32.MaxValue."); Debug.Assert(dataBuffers != null, "'dataBuffers' MUST NOT be NULL."); ThrowIfDisposed(); if (dataBufferCount > dataBuffers.Length) { Debug.Assert(false, "'dataBufferCount' MUST NOT be bigger than 'dataBuffers.Length'."); // Indicates a violation in the contract with native Websocket.dll and could indicate // memory corruption because the internal buffer is shared between managed and native code throw new AccessViolationException(); } int count = dataBuffers.Length; bool isSendActivity = action == WebSocketProtocolComponent.Action.IndicateSendComplete || action == WebSocketProtocolComponent.Action.SendToNetwork; if (isSendActivity) { count = (int)dataBufferCount; } bool nonZeroBufferFound = false; for (int i = 0; i < count; i++) { Interop.WebSocket.Buffer dataBuffer = dataBuffers[i]; IntPtr bufferData; uint bufferLength; UnwrapWebSocketBuffer(dataBuffer, bufferType, out bufferData, out bufferLength); if (bufferData == IntPtr.Zero) { continue; } nonZeroBufferFound = true; bool isPinnedSendPayloadBuffer = IsPinnedSendPayloadBuffer(dataBuffer, bufferType); if (bufferLength > GetMaxBufferSize()) { if (!isSendActivity || !isPinnedSendPayloadBuffer) { Debug.Assert(false, "'dataBuffer.BufferLength' MUST NOT be bigger than 'm_ReceiveBufferSize' and 'm_SendBufferSize'."); // Indicates a violation in the contract with native Websocket.dll and could indicate // memory corruption because the internal buffer is shared between managed and native code throw new AccessViolationException(); } } if (!isPinnedSendPayloadBuffer && !IsNativeBuffer(bufferData, bufferLength)) { Debug.Assert(false, "WebSocketGetAction MUST return a pointer within the pinned internal buffer."); // Indicates a violation in the contract with native Websocket.dll and could indicate // memory corruption because the internal buffer is shared between managed and native code throw new AccessViolationException(); } } if (!nonZeroBufferFound && action != WebSocketProtocolComponent.Action.NoAction && action != WebSocketProtocolComponent.Action.IndicateReceiveComplete && action != WebSocketProtocolComponent.Action.IndicateSendComplete) { Debug.Assert(false, "At least one 'dataBuffer.Buffer' MUST NOT be NULL."); } }