message.h (25615B)
1 // Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #pragma once 23 24 #include <kj/common.h> 25 #include <kj/memory.h> 26 #include <kj/mutex.h> 27 #include <kj/debug.h> 28 #include <kj/vector.h> 29 #include "common.h" 30 #include "layout.h" 31 #include "any.h" 32 33 CAPNP_BEGIN_HEADER 34 35 namespace capnp { 36 37 namespace _ { // private 38 class ReaderArena; 39 class BuilderArena; 40 struct CloneImpl; 41 } 42 43 class StructSchema; 44 class Orphanage; 45 template <typename T> 46 class Orphan; 47 48 // ======================================================================================= 49 50 struct ReaderOptions { 51 // Options controlling how data is read. 52 53 uint64_t traversalLimitInWords = 8 * 1024 * 1024; 54 // Limits how many total words of data are allowed to be traversed. Traversal is counted when 55 // a new struct or list builder is obtained, e.g. from a get() accessor. This means that calling 56 // the getter for the same sub-struct multiple times will cause it to be double-counted. Once 57 // the traversal limit is reached, an error will be reported. 58 // 59 // This limit exists for security reasons. It is possible for an attacker to construct a message 60 // in which multiple pointers point at the same location. This is technically invalid, but hard 61 // to detect. Using such a message, an attacker could cause a message which is small on the wire 62 // to appear much larger when actually traversed, possibly exhausting server resources leading to 63 // denial-of-service. 64 // 65 // It makes sense to set a traversal limit that is much larger than the underlying message. 66 // Together with sensible coding practices (e.g. trying to avoid calling sub-object getters 67 // multiple times, which is expensive anyway), this should provide adequate protection without 68 // inconvenience. 69 // 70 // The default limit is 64 MiB. This may or may not be a sensible number for any given use case, 71 // but probably at least prevents easy exploitation while also avoiding causing problems in most 72 // typical cases. 73 74 int nestingLimit = 64; 75 // Limits how deeply-nested a message structure can be, e.g. structs containing other structs or 76 // lists of structs. 77 // 78 // Like the traversal limit, this limit exists for security reasons. Since it is common to use 79 // recursive code to traverse recursive data structures, an attacker could easily cause a stack 80 // overflow by sending a very-deeply-nested (or even cyclic) message, without the message even 81 // being very large. The default limit of 64 is probably low enough to prevent any chance of 82 // stack overflow, yet high enough that it is never a problem in practice. 83 }; 84 85 class MessageReader { 86 // Abstract interface for an object used to read a Cap'n Proto message. Subclasses of 87 // MessageReader are responsible for reading the raw, flat message content. Callers should 88 // usually call `messageReader.getRoot<MyStructType>()` to get a `MyStructType::Reader` 89 // representing the root of the message, then use that to traverse the message content. 90 // 91 // Some common subclasses of `MessageReader` include `SegmentArrayMessageReader`, whose 92 // constructor accepts pointers to the raw data, and `StreamFdMessageReader` (from 93 // `serialize.h`), which reads the message from a file descriptor. One might implement other 94 // subclasses to handle things like reading from shared memory segments, mmap()ed files, etc. 95 96 public: 97 MessageReader(ReaderOptions options); 98 // It is suggested that subclasses take ReaderOptions as a constructor parameter, but give it a 99 // default value of "ReaderOptions()". The base class constructor doesn't have a default value 100 // in order to remind subclasses that they really need to give the user a way to provide this. 101 102 virtual ~MessageReader() noexcept(false); 103 104 virtual kj::ArrayPtr<const word> getSegment(uint id) = 0; 105 // Gets the segment with the given ID, or returns null if no such segment exists. This method 106 // will be called at most once for each segment ID. 107 108 inline const ReaderOptions& getOptions(); 109 // Get the options passed to the constructor. 110 111 template <typename RootType> 112 typename RootType::Reader getRoot(); 113 // Get the root struct of the message, interpreting it as the given struct type. 114 115 template <typename RootType, typename SchemaType> 116 typename RootType::Reader getRoot(SchemaType schema); 117 // Dynamically interpret the root struct of the message using the given schema (a StructSchema). 118 // RootType in this case must be DynamicStruct, and you must #include <capnp/dynamic.h> to 119 // use this. 120 121 bool isCanonical(); 122 // Returns whether the message encoded in the reader is in canonical form. 123 124 size_t sizeInWords(); 125 // Add up the size of all segments. 126 127 private: 128 ReaderOptions options; 129 130 #if defined(__EMSCRIPTEN__) 131 static constexpr size_t arenaSpacePadding = 19; 132 #else 133 static constexpr size_t arenaSpacePadding = 18; 134 #endif 135 136 // Space in which we can construct a ReaderArena. We don't use ReaderArena directly here 137 // because we don't want clients to have to #include arena.h, which itself includes a bunch of 138 // other headers. We don't use a pointer to a ReaderArena because that would require an 139 // extra malloc on every message which could be expensive when processing small messages. 140 alignas(8) void* arenaSpace[arenaSpacePadding + sizeof(kj::MutexGuarded<void*>) / sizeof(void*)]; 141 bool allocatedArena; 142 143 _::ReaderArena* arena() { return reinterpret_cast<_::ReaderArena*>(arenaSpace); } 144 AnyPointer::Reader getRootInternal(); 145 }; 146 147 class MessageBuilder { 148 // Abstract interface for an object used to allocate and build a message. Subclasses of 149 // MessageBuilder are responsible for allocating the space in which the message will be written. 150 // The most common subclass is `MallocMessageBuilder`, but other subclasses may be used to do 151 // tricky things like allocate messages in shared memory or mmap()ed files. 152 // 153 // Creating a new message ususually means allocating a new MessageBuilder (ideally on the stack) 154 // and then calling `messageBuilder.initRoot<MyStructType>()` to get a `MyStructType::Builder`. 155 // That, in turn, can be used to fill in the message content. When done, you can call 156 // `messageBuilder.getSegmentsForOutput()` to get a list of flat data arrays containing the 157 // message. 158 159 public: 160 MessageBuilder(); 161 virtual ~MessageBuilder() noexcept(false); 162 KJ_DISALLOW_COPY(MessageBuilder); 163 164 struct SegmentInit { 165 kj::ArrayPtr<word> space; 166 167 size_t wordsUsed; 168 // Number of words in `space` which are used; the rest are free space in which additional 169 // objects may be allocated. 170 }; 171 172 explicit MessageBuilder(kj::ArrayPtr<SegmentInit> segments); 173 // Create a MessageBuilder backed by existing memory. This is an advanced interface that most 174 // people should not use. THIS METHOD IS INSECURE; see below. 175 // 176 // This allows a MessageBuilder to be constructed to modify an in-memory message without first 177 // making a copy of the content. This is especially useful in conjunction with mmap(). 178 // 179 // The contents of each segment must outlive the MessageBuilder, but the SegmentInit array itself 180 // only need outlive the constructor. 181 // 182 // SECURITY: Do not use this in conjunction with untrusted data. This constructor assumes that 183 // the input message is valid. This constructor is designed to be used with data you control, 184 // e.g. an mmap'd file which is owned and accessed by only one program. When reading data you 185 // do not trust, you *must* load it into a Reader and then copy into a Builder as a means of 186 // validating the content. 187 // 188 // WARNING: It is NOT safe to initialize a MessageBuilder in this way from memory that is 189 // currently in use by another MessageBuilder or MessageReader. Other readers/builders will 190 // not observe changes to the segment sizes nor newly-allocated segments caused by allocating 191 // new objects in this message. 192 193 virtual kj::ArrayPtr<word> allocateSegment(uint minimumSize) = 0; 194 // Allocates an array of at least the given number of zero'd words, throwing an exception or 195 // crashing if this is not possible. It is expected that this method will usually return more 196 // space than requested, and the caller should use that extra space as much as possible before 197 // allocating more. The returned space remains valid at least until the MessageBuilder is 198 // destroyed. 199 // 200 // allocateSegment() is responsible for zeroing the memory before returning. This is required 201 // because otherwise the Cap'n Proto implementation would have to zero the memory anyway, and 202 // many allocators are able to provide already-zero'd memory more efficiently. 203 204 template <typename RootType> 205 typename RootType::Builder initRoot(); 206 // Initialize the root struct of the message as the given struct type. 207 208 template <typename Reader> 209 void setRoot(Reader&& value); 210 // Set the root struct to a deep copy of the given struct. 211 212 template <typename RootType> 213 typename RootType::Builder getRoot(); 214 // Get the root struct of the message, interpreting it as the given struct type. 215 216 template <typename RootType, typename SchemaType> 217 typename RootType::Builder getRoot(SchemaType schema); 218 // Dynamically interpret the root struct of the message using the given schema (a StructSchema). 219 // RootType in this case must be DynamicStruct, and you must #include <capnp/dynamic.h> to 220 // use this. 221 222 template <typename RootType, typename SchemaType> 223 typename RootType::Builder initRoot(SchemaType schema); 224 // Dynamically init the root struct of the message using the given schema (a StructSchema). 225 // RootType in this case must be DynamicStruct, and you must #include <capnp/dynamic.h> to 226 // use this. 227 228 template <typename T> 229 void adoptRoot(Orphan<T>&& orphan); 230 // Like setRoot() but adopts the orphan without copying. 231 232 kj::ArrayPtr<const kj::ArrayPtr<const word>> getSegmentsForOutput(); 233 // Get the raw data that makes up the message. 234 235 Orphanage getOrphanage(); 236 237 bool isCanonical(); 238 // Check whether the message builder is in canonical form 239 240 size_t sizeInWords(); 241 // Add up the allocated space from all segments. 242 243 private: 244 alignas(8) void* arenaSpace[22]; 245 // Space in which we can construct a BuilderArena. We don't use BuilderArena directly here 246 // because we don't want clients to have to #include arena.h, which itself includes a bunch of 247 // big STL headers. We don't use a pointer to a BuilderArena because that would require an 248 // extra malloc on every message which could be expensive when processing small messages. 249 250 bool allocatedArena = false; 251 // We have to initialize the arena lazily because when we do so we want to allocate the root 252 // pointer immediately, and this will allocate a segment, which requires a virtual function 253 // call on the MessageBuilder. We can't do such a call in the constructor since the subclass 254 // isn't constructed yet. This is kind of annoying because it means that getOrphanage() is 255 // not thread-safe, but that shouldn't be a huge deal... 256 257 _::BuilderArena* arena() { return reinterpret_cast<_::BuilderArena*>(arenaSpace); } 258 _::SegmentBuilder* getRootSegment(); 259 AnyPointer::Builder getRootInternal(); 260 261 kj::Own<_::CapTableBuilder> releaseBuiltinCapTable(); 262 // Hack for clone() to extract the cap table. 263 264 friend struct _::CloneImpl; 265 // We can't declare clone() as a friend directly because old versions of GCC incorrectly demand 266 // that the first declaration (even if it is a friend declaration) specify the default type args, 267 // whereas correct compilers do not permit default type args to be specified on a friend decl. 268 }; 269 270 template <typename RootType> 271 typename RootType::Reader readMessageUnchecked(const word* data); 272 // IF THE INPUT IS INVALID, THIS MAY CRASH, CORRUPT MEMORY, CREATE A SECURITY HOLE IN YOUR APP, 273 // MURDER YOUR FIRST-BORN CHILD, AND/OR BRING ABOUT ETERNAL DAMNATION ON ALL OF HUMANITY. DO NOT 274 // USE UNLESS YOU UNDERSTAND THE CONSEQUENCES. 275 // 276 // Given a pointer to a known-valid message located in a single contiguous memory segment, 277 // returns a reader for that message. No bounds-checking will be done while traversing this 278 // message. Use this only if you have already verified that all pointers are valid and in-bounds, 279 // and there are no far pointers in the message. 280 // 281 // To create a message that can be passed to this function, build a message using a MallocAllocator 282 // whose preferred segment size is larger than the message size. This guarantees that the message 283 // will be allocated as a single segment, meaning getSegmentsForOutput() returns a single word 284 // array. That word array is your message; you may pass a pointer to its first word into 285 // readMessageUnchecked() to read the message. 286 // 287 // This can be particularly handy for embedding messages in generated code: you can 288 // embed the raw bytes (using AlignedData) then make a Reader for it using this. This is the way 289 // default values are embedded in code generated by the Cap'n Proto compiler. E.g., if you have 290 // a message MyMessage, you can read its default value like so: 291 // MyMessage::Reader reader = Message<MyMessage>::readMessageUnchecked(MyMessage::DEFAULT.words); 292 // 293 // To sanitize a message from an untrusted source such that it can be safely passed to 294 // readMessageUnchecked(), use copyToUnchecked(). 295 296 template <typename Reader> 297 void copyToUnchecked(Reader&& reader, kj::ArrayPtr<word> uncheckedBuffer); 298 // Copy the content of the given reader into the given buffer, such that it can safely be passed to 299 // readMessageUnchecked(). The buffer's size must be exactly reader.totalSizeInWords() + 1, 300 // otherwise an exception will be thrown. The buffer must be zero'd before calling. 301 302 template <typename RootType> 303 typename RootType::Reader readDataStruct(kj::ArrayPtr<const word> data); 304 // Interprets the given data as a single, data-only struct. Only primitive fields (booleans, 305 // numbers, and enums) will be readable; all pointers will be null. This is useful if you want 306 // to use Cap'n Proto as a language/platform-neutral way to pack some bits. 307 // 308 // The input is a word array rather than a byte array to enforce alignment. If you have a byte 309 // array which you know is word-aligned (or if your platform supports unaligned reads and you don't 310 // mind the performance penalty), then you can use `reinterpret_cast` to convert a byte array into 311 // a word array: 312 // 313 // kj::arrayPtr(reinterpret_cast<const word*>(bytes.begin()), 314 // reinterpret_cast<const word*>(bytes.end())) 315 316 template <typename BuilderType> 317 typename kj::ArrayPtr<const word> writeDataStruct(BuilderType builder); 318 // Given a struct builder, get the underlying data section as a word array, suitable for passing 319 // to `readDataStruct()`. 320 // 321 // Note that you may call `.toBytes()` on the returned value to convert to `ArrayPtr<const byte>`. 322 323 template <typename Type> 324 static typename Type::Reader defaultValue(); 325 // Get a default instance of the given struct or list type. 326 // 327 // TODO(cleanup): Find a better home for this function? 328 329 template <typename Reader, typename = FromReader<Reader>> 330 kj::Own<kj::Decay<Reader>> clone(Reader&& reader); 331 // Make a deep copy of the given Reader on the heap, producing an owned pointer. 332 333 // ======================================================================================= 334 335 class SegmentArrayMessageReader: public MessageReader { 336 // A simple MessageReader that reads from an array of word arrays representing all segments. 337 // In particular you can read directly from the output of MessageBuilder::getSegmentsForOutput() 338 // (although it would probably make more sense to call builder.getRoot().asReader() in that case). 339 340 public: 341 SegmentArrayMessageReader(kj::ArrayPtr<const kj::ArrayPtr<const word>> segments, 342 ReaderOptions options = ReaderOptions()); 343 // Creates a message pointing at the given segment array, without taking ownership of the 344 // segments. All arrays passed in must remain valid until the MessageReader is destroyed. 345 346 KJ_DISALLOW_COPY(SegmentArrayMessageReader); 347 ~SegmentArrayMessageReader() noexcept(false); 348 349 virtual kj::ArrayPtr<const word> getSegment(uint id) override; 350 351 private: 352 kj::ArrayPtr<const kj::ArrayPtr<const word>> segments; 353 }; 354 355 enum class AllocationStrategy: uint8_t { 356 FIXED_SIZE, 357 // The builder will prefer to allocate the same amount of space for each segment with no 358 // heuristic growth. It will still allocate larger segments when the preferred size is too small 359 // for some single object. This mode is generally not recommended, but can be particularly useful 360 // for testing in order to force a message to allocate a predictable number of segments. Note 361 // that you can force every single object in the message to be located in a separate segment by 362 // using this mode with firstSegmentWords = 0. 363 364 GROW_HEURISTICALLY 365 // The builder will heuristically decide how much space to allocate for each segment. Each 366 // allocated segment will be progressively larger than the previous segments on the assumption 367 // that message sizes are exponentially distributed. The total number of segments that will be 368 // allocated for a message of size n is O(log n). 369 }; 370 371 constexpr uint SUGGESTED_FIRST_SEGMENT_WORDS = 1024; 372 constexpr AllocationStrategy SUGGESTED_ALLOCATION_STRATEGY = AllocationStrategy::GROW_HEURISTICALLY; 373 374 class MallocMessageBuilder: public MessageBuilder { 375 // A simple MessageBuilder that uses malloc() (actually, calloc()) to allocate segments. This 376 // implementation should be reasonable for any case that doesn't require writing the message to 377 // a specific location in memory. 378 379 public: 380 explicit MallocMessageBuilder(uint firstSegmentWords = SUGGESTED_FIRST_SEGMENT_WORDS, 381 AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); 382 // Creates a BuilderContext which allocates at least the given number of words for the first 383 // segment, and then uses the given strategy to decide how much to allocate for subsequent 384 // segments. When choosing a value for firstSegmentWords, consider that: 385 // 1) Reading and writing messages gets slower when multiple segments are involved, so it's good 386 // if most messages fit in a single segment. 387 // 2) Unused bytes will not be written to the wire, so generally it is not a big deal to allocate 388 // more space than you need. It only becomes problematic if you are allocating many messages 389 // in parallel and thus use lots of memory, or if you allocate so much extra space that just 390 // zeroing it out becomes a bottleneck. 391 // The defaults have been chosen to be reasonable for most people, so don't change them unless you 392 // have reason to believe you need to. 393 394 explicit MallocMessageBuilder(kj::ArrayPtr<word> firstSegment, 395 AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); 396 // This version always returns the given array for the first segment, and then proceeds with the 397 // allocation strategy. This is useful for optimization when building lots of small messages in 398 // a tight loop: you can reuse the space for the first segment. 399 // 400 // firstSegment MUST be zero-initialized. MallocMessageBuilder's destructor will write new zeros 401 // over any space that was used so that it can be reused. 402 403 KJ_DISALLOW_COPY(MallocMessageBuilder); 404 virtual ~MallocMessageBuilder() noexcept(false); 405 406 virtual kj::ArrayPtr<word> allocateSegment(uint minimumSize) override; 407 408 private: 409 uint nextSize; 410 AllocationStrategy allocationStrategy; 411 412 bool ownFirstSegment; 413 bool returnedFirstSegment; 414 415 void* firstSegment; 416 kj::Vector<void*> moreSegments; 417 }; 418 419 class FlatMessageBuilder: public MessageBuilder { 420 // THIS IS NOT THE CLASS YOU'RE LOOKING FOR. 421 // 422 // If you want to write a message into already-existing scratch space, use `MallocMessageBuilder` 423 // and pass the scratch space to its constructor. It will then only fall back to malloc() if 424 // the scratch space is not large enough. 425 // 426 // Do NOT use this class unless you really know what you're doing. This class is problematic 427 // because it requires advance knowledge of the size of your message, which is usually impossible 428 // to determine without actually building the message. The class was created primarily to 429 // implement `copyToUnchecked()`, which itself exists only to support other internal parts of 430 // the Cap'n Proto implementation. 431 432 public: 433 explicit FlatMessageBuilder(kj::ArrayPtr<word> array); 434 KJ_DISALLOW_COPY(FlatMessageBuilder); 435 virtual ~FlatMessageBuilder() noexcept(false); 436 437 void requireFilled(); 438 // Throws an exception if the flat array is not exactly full. 439 440 virtual kj::ArrayPtr<word> allocateSegment(uint minimumSize) override; 441 442 private: 443 kj::ArrayPtr<word> array; 444 bool allocated; 445 }; 446 447 // ======================================================================================= 448 // implementation details 449 450 inline const ReaderOptions& MessageReader::getOptions() { 451 return options; 452 } 453 454 template <typename RootType> 455 inline typename RootType::Reader MessageReader::getRoot() { 456 return getRootInternal().getAs<RootType>(); 457 } 458 459 template <typename RootType> 460 inline typename RootType::Builder MessageBuilder::initRoot() { 461 return getRootInternal().initAs<RootType>(); 462 } 463 464 template <typename Reader> 465 inline void MessageBuilder::setRoot(Reader&& value) { 466 getRootInternal().setAs<FromReader<Reader>>(value); 467 } 468 469 template <typename RootType> 470 inline typename RootType::Builder MessageBuilder::getRoot() { 471 return getRootInternal().getAs<RootType>(); 472 } 473 474 template <typename T> 475 void MessageBuilder::adoptRoot(Orphan<T>&& orphan) { 476 return getRootInternal().adopt(kj::mv(orphan)); 477 } 478 479 template <typename RootType, typename SchemaType> 480 typename RootType::Reader MessageReader::getRoot(SchemaType schema) { 481 return getRootInternal().getAs<RootType>(schema); 482 } 483 484 template <typename RootType, typename SchemaType> 485 typename RootType::Builder MessageBuilder::getRoot(SchemaType schema) { 486 return getRootInternal().getAs<RootType>(schema); 487 } 488 489 template <typename RootType, typename SchemaType> 490 typename RootType::Builder MessageBuilder::initRoot(SchemaType schema) { 491 return getRootInternal().initAs<RootType>(schema); 492 } 493 494 template <typename RootType> 495 typename RootType::Reader readMessageUnchecked(const word* data) { 496 return AnyPointer::Reader(_::PointerReader::getRootUnchecked(data)).getAs<RootType>(); 497 } 498 499 template <typename Reader> 500 void copyToUnchecked(Reader&& reader, kj::ArrayPtr<word> uncheckedBuffer) { 501 FlatMessageBuilder builder(uncheckedBuffer); 502 builder.setRoot(kj::fwd<Reader>(reader)); 503 builder.requireFilled(); 504 } 505 506 template <typename RootType> 507 typename RootType::Reader readDataStruct(kj::ArrayPtr<const word> data) { 508 return typename RootType::Reader(_::StructReader(data)); 509 } 510 511 template <typename BuilderType> 512 typename kj::ArrayPtr<const word> writeDataStruct(BuilderType builder) { 513 auto bytes = _::PointerHelpers<FromBuilder<BuilderType>>::getInternalBuilder(kj::mv(builder)) 514 .getDataSectionAsBlob(); 515 return kj::arrayPtr(reinterpret_cast<word*>(bytes.begin()), 516 reinterpret_cast<word*>(bytes.end())); 517 } 518 519 template <typename Type> 520 static typename Type::Reader defaultValue() { 521 return typename Type::Reader(_::StructReader()); 522 } 523 524 namespace _ { 525 struct CloneImpl { 526 static inline kj::Own<_::CapTableBuilder> releaseBuiltinCapTable(MessageBuilder& message) { 527 return message.releaseBuiltinCapTable(); 528 } 529 }; 530 }; 531 532 template <typename Reader, typename> 533 kj::Own<kj::Decay<Reader>> clone(Reader&& reader) { 534 auto size = reader.totalSize(); 535 auto buffer = kj::heapArray<capnp::word>(size.wordCount + 1); 536 memset(buffer.asBytes().begin(), 0, buffer.asBytes().size()); 537 if (size.capCount == 0) { 538 copyToUnchecked(reader, buffer); 539 auto result = readMessageUnchecked<FromReader<Reader>>(buffer.begin()); 540 return kj::attachVal(result, kj::mv(buffer)); 541 } else { 542 FlatMessageBuilder builder(buffer); 543 builder.setRoot(kj::fwd<Reader>(reader)); 544 builder.requireFilled(); 545 auto capTable = _::CloneImpl::releaseBuiltinCapTable(builder); 546 AnyPointer::Reader raw(_::PointerReader::getRootUnchecked(buffer.begin()).imbue(capTable)); 547 return kj::attachVal(raw.getAs<FromReader<Reader>>(), kj::mv(buffer), kj::mv(capTable)); 548 } 549 } 550 551 template <typename T> 552 kj::Array<word> canonicalize(T&& reader) { 553 return _::PointerHelpers<FromReader<T>>::getInternalReader(reader).canonicalize(); 554 } 555 556 } // namespace capnp 557 558 CAPNP_END_HEADER