Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

Upload of page blob with stream size >4MB fails silently #404

@ShippyMSFT

Description

@ShippyMSFT

Recently we noticed an issue where uploads of page blobs using a stream size of more than 4MB were completing unrealistically fast. Through some extra investigation we found that 4MB is the max, but the SDK does not throw any error to us in this case so it appears everything completed really quickly.

In istream_descriptor::create() it correctly throws std::invalid_argument in this case:

if (length != std::numeric_limits<utility::size64_t>::max() && length > max_length)
{
    throw std::invalid_argument(protocol::error_stream_length);
}

However, the implementation in basic_cloud_page_blob_ostreambuf::upload_buffer() doesn't set any current exception info:

            try
            {
                this_pointer->m_blob->upload_pages_async_impl(buffer->stream(), offset, buffer->content_checksum(), this_pointer->m_condition, this_pointer->m_options, this_pointer->m_context, this_pointer->m_cancellation_token, this_pointer->m_use_request_level_timeout, this_pointer->m_timer_handler).then([this_pointer] (pplx::task<void> upload_task)
                {
                    std::lock_guard<async_semaphore> guard(this_pointer->m_semaphore, std::adopt_lock);
                    try
                    {
                        upload_task.wait();
                    }
                    catch (const std::exception&)
                    {
                        this_pointer->m_currentException = std::current_exception();
                    }
                });
            }
            catch (...)
            {
                this_pointer->m_semaphore.unlock();  <-- We end up here
            }

Since m_currentException is not set here, the error is not processed at the end in basic_cloud_blob_ostreambuf::_sync() and it returns as if the operation were successful. While it can be worked around once the issue is understood, it is a data integrity issue if gone unnoticed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions