Changeset 252855 in webkit
- Timestamp:
- Nov 25, 2019 6:33:13 AM (4 years ago)
- Location:
- trunk/Source/WTF
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r252853 r252855 1 1 2019-11-25 Carlos Garcia Campos <cgarcia@igalia.com> 2 2 3 REGRESSION(r252770): [GTK][WPE] Remove inspector broken in debug builds after r252770 3 REGRESSION(r252770): [GTK][WPE] Remote inspector no longer works if debugger is in a different kind of system 4 https://bugs.webkit.org/show_bug.cgi?id=204572 5 6 Reviewed by Žan Doberšek. 7 8 This patch adds the following changes: 9 10 - Use uint32_t instead of size_t to store the body size in the message header, because size_t has a different 11 size in 32 and 64 bit platforms. 12 - Use htonl/ntohl to write/read the body size in the header. 13 - Add a flags byte to the header to include the message byte order. The sender always uses the host byter order 14 and the receiver does the byte swapping if needed. 15 16 * wtf/glib/SocketConnection.cpp: 17 (WTF::messageIsByteSwapped): 18 (WTF::SocketConnection::readMessage): 19 (WTF::SocketConnection::sendMessage): 20 21 2019-11-25 Carlos Garcia Campos <cgarcia@igalia.com> 22 23 REGRESSION(r252770): [GTK][WPE] Remote inspector broken in debug builds after r252770 4 24 https://bugs.webkit.org/show_bug.cgi?id=204569 5 25 -
trunk/Source/WTF/wtf/glib/SocketConnection.cpp
r252853 r252855 23 23 #include <cstring> 24 24 #include <gio/gio.h> 25 #include <wtf/ByteOrder.h> 26 #include <wtf/CheckedArithmetic.h> 25 27 #include <wtf/FastMalloc.h> 26 28 #include <wtf/RunLoop.h> … … 94 96 } 95 97 98 enum { 99 ByteOrderLittleEndian = 1 << 0 100 }; 101 typedef uint8_t MessageFlags; 102 103 static inline bool messageIsByteSwapped(MessageFlags flags) 104 { 105 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 106 return !(flags & ByteOrderLittleEndian); 107 #else 108 return (flags & ByteOrderLittleEndian); 109 #endif 110 } 111 96 112 bool SocketConnection::readMessage() 97 113 { 98 if (m_readBuffer.size() < sizeof( size_t))114 if (m_readBuffer.size() < sizeof(uint32_t)) 99 115 return false; 100 116 101 117 auto* messageData = m_readBuffer.data(); 102 size_t bodySize; 103 memcpy(&bodySize, messageData, sizeof(size_t)); 104 messageData += sizeof(size_t); 105 auto messageSize = sizeof(size_t) + bodySize; 106 if (m_readBuffer.size() < messageSize) 118 uint32_t bodySizeHeader; 119 memcpy(&bodySizeHeader, messageData, sizeof(uint32_t)); 120 messageData += sizeof(uint32_t); 121 bodySizeHeader = ntohl(bodySizeHeader); 122 Checked<size_t> bodySize = bodySizeHeader; 123 MessageFlags flags; 124 memcpy(&flags, messageData, sizeof(MessageFlags)); 125 messageData += sizeof(MessageFlags); 126 auto messageSize = sizeof(uint32_t) + sizeof(MessageFlags) + bodySize; 127 if (m_readBuffer.size() < messageSize.unsafeGet()) 107 128 return false; 108 129 109 auto messageNameLength = strlen(messageData) + 1; 110 if (m_readBuffer.size() < messageNameLength) { 130 Checked<size_t> messageNameLength = strlen(messageData); 131 messageNameLength++; 132 if (m_readBuffer.size() < messageNameLength.unsafeGet()) { 111 133 ASSERT_NOT_REACHED(); 112 134 return false; … … 115 137 const auto it = m_messageHandlers.find(messageData); 116 138 if (it != m_messageHandlers.end()) { 117 messageData += messageNameLength ;139 messageData += messageNameLength.unsafeGet(); 118 140 GRefPtr<GVariant> parameters; 119 141 if (!it->value.first.isNull()) { 120 142 GUniquePtr<GVariantType> variantType(g_variant_type_new(it->value.first.data())); 143 size_t parametersSize = bodySize.unsafeGet() - messageNameLength.unsafeGet(); 121 144 // g_variant_new_from_data() requires the memory to be properly aligned for the type being loaded, 122 145 // but it's not possible to know the alignment because g_variant_type_info_query() is not public API. … … 124 147 // in aligned memory only if needed. For older versions we can simply ensure the memory is 8 aligned. 125 148 #if GLIB_CHECK_VERSION(2, 60, 0) 126 parameters = g_variant_new_from_data(variantType.get(), messageData, bodySize - messageNameLength, FALSE, nullptr, nullptr);149 parameters = g_variant_new_from_data(variantType.get(), messageData, parametersSize, FALSE, nullptr, nullptr); 127 150 #else 128 auto* alignedMemory = fastAlignedMalloc(8, bodySize - messageNameLength);129 memcpy(alignedMemory, messageData, bodySize - messageNameLength);130 GRefPtr<GBytes> bytes = g_bytes_new_with_free_func(alignedMemory, bodySize - messageNameLength, [](gpointer data) {151 auto* alignedMemory = fastAlignedMalloc(8, parametersSize); 152 memcpy(alignedMemory, messageData, parametersSize); 153 GRefPtr<GBytes> bytes = g_bytes_new_with_free_func(alignedMemory, parametersSize, [](gpointer data) { 131 154 fastAlignedFree(data); 132 155 }, alignedMemory); 133 156 parameters = g_variant_new_from_bytes(variantType.get(), bytes.get(), FALSE); 134 157 #endif 158 if (messageIsByteSwapped(flags)) 159 parameters = adoptGRef(g_variant_byteswap(parameters.get())); 135 160 } 136 161 it->value.second(*this, parameters.get(), m_userData); … … 139 164 } 140 165 141 if (m_readBuffer.size() > messageSize ) {142 std::memmove(m_readBuffer.data(), m_readBuffer.data() + messageSize , m_readBuffer.size() - messageSize);143 m_readBuffer.shrink(m_readBuffer.size() - messageSize );166 if (m_readBuffer.size() > messageSize.unsafeGet()) { 167 std::memmove(m_readBuffer.data(), m_readBuffer.data() + messageSize.unsafeGet(), m_readBuffer.size() - messageSize.unsafeGet()); 168 m_readBuffer.shrink(m_readBuffer.size() - messageSize.unsafeGet()); 144 169 } else 145 170 m_readBuffer.shrink(0); … … 155 180 GRefPtr<GVariant> adoptedParameters = parameters; 156 181 size_t parametersSize = parameters ? g_variant_get_size(parameters) : 0; 157 auto messageNameLength = strlen(messageName) + 1; 158 size_t bodySize = messageNameLength + parametersSize; 182 Checked<size_t, RecordOverflow> messageNameLength = strlen(messageName); 183 messageNameLength++; 184 if (UNLIKELY(messageNameLength.hasOverflowed())) { 185 g_warning("Trying to send message with invalid too long name"); 186 return; 187 } 188 Checked<uint32_t, RecordOverflow> bodySize = messageNameLength + parametersSize; 189 if (UNLIKELY(bodySize.hasOverflowed())) { 190 g_warning("Trying to send message '%s' with invalid too long body", messageName); 191 return; 192 } 159 193 size_t previousBufferSize = m_writeBuffer.size(); 160 m_writeBuffer.grow(previousBufferSize + sizeof( size_t) + bodySize);194 m_writeBuffer.grow(previousBufferSize + sizeof(uint32_t) + sizeof(MessageFlags) + bodySize.unsafeGet()); 161 195 162 196 auto* messageData = m_writeBuffer.data() + previousBufferSize; 163 memcpy(messageData, &bodySize, sizeof(size_t)); 164 messageData += sizeof(size_t); 165 memcpy(messageData, messageName, messageNameLength); 166 messageData += messageNameLength; 197 uint32_t bodySizeHeader = htonl(bodySize.unsafeGet()); 198 memcpy(messageData, &bodySizeHeader, sizeof(uint32_t)); 199 messageData += sizeof(uint32_t); 200 MessageFlags flags = 0; 201 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 202 flags |= ByteOrderLittleEndian; 203 #endif 204 memcpy(messageData, &flags, sizeof(MessageFlags)); 205 messageData += sizeof(MessageFlags); 206 memcpy(messageData, messageName, messageNameLength.unsafeGet()); 207 messageData += messageNameLength.unsafeGet(); 167 208 if (parameters) 168 209 memcpy(messageData, g_variant_get_data(parameters), parametersSize);
Note: See TracChangeset
for help on using the changeset viewer.