Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/installer/corehost/cli/apphost/bundle/reader.cpp')
-rw-r--r--src/installer/corehost/cli/apphost/bundle/reader.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/installer/corehost/cli/apphost/bundle/reader.cpp b/src/installer/corehost/cli/apphost/bundle/reader.cpp
new file mode 100644
index 00000000000..e2fa9b6574c
--- /dev/null
+++ b/src/installer/corehost/cli/apphost/bundle/reader.cpp
@@ -0,0 +1,98 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "reader.h"
+#include "error_codes.h"
+#include "trace.h"
+
+using namespace bundle;
+
+const int8_t* reader_t::add_without_overflow(const int8_t* ptr, int64_t len)
+{
+ const int8_t* new_ptr = ptr + len;
+
+ // The following check will fail in case len < 0 (which is also an error while reading)
+ // even if the actual arthmetic didn't overflow.
+ if (new_ptr < ptr)
+ {
+ trace::error(_X("Failure processing application bundle; possible file corruption."));
+ trace::error(_X("Arithmetic overflow computing bundle-bounds."));
+ throw StatusCode::BundleExtractionFailure;
+ }
+
+ return new_ptr;
+}
+
+void reader_t::set_offset(int64_t offset)
+{
+ if (offset < 0 || offset >= m_bound)
+ {
+ trace::error(_X("Failure processing application bundle; possible file corruption."));
+ trace::error(_X("Arithmetic overflow while reading bundle."));
+ throw StatusCode::BundleExtractionFailure;
+ }
+
+ m_ptr = m_base_ptr + offset;
+}
+
+void reader_t::bounds_check(int64_t len)
+{
+ const int8_t* post_read_ptr = add_without_overflow(m_ptr, len);
+
+ // It is legal for post_read_ptr == m_bound_ptr after reading the last byte.
+ if (m_ptr < m_base_ptr || post_read_ptr > m_bound_ptr)
+ {
+ trace::error(_X("Failure processing application bundle; possible file corruption."));
+ trace::error(_X("Bounds check failed while reading the bundle."));
+ throw StatusCode::BundleExtractionFailure;
+ }
+}
+
+// Handle the relatively uncommon scenario where the bundle ID or
+// the relative-path of a file within the bundle is longer than 127 bytes
+size_t reader_t::read_path_length()
+{
+ size_t length = 0;
+
+ int8_t first_byte = read();
+
+ // If the high bit is set, it means there are more bytes to read.
+ if ((first_byte & 0x80) == 0)
+ {
+ length = first_byte;
+ }
+ else
+ {
+ int8_t second_byte = read();
+
+ if (second_byte & 0x80)
+ {
+ // There can be no more than two bytes in path_length
+ trace::error(_X("Failure processing application bundle; possible file corruption."));
+ trace::error(_X("Path length encoding read beyond two bytes."));
+
+ throw StatusCode::BundleExtractionFailure;
+ }
+
+ length = (second_byte << 7) | (first_byte & 0x7f);
+ }
+
+ if (length <= 0 || length > PATH_MAX)
+ {
+ trace::error(_X("Failure processing application bundle; possible file corruption."));
+ trace::error(_X("Path length is zero or too long."));
+ throw StatusCode::BundleExtractionFailure;
+ }
+
+ return length;
+}
+
+void reader_t::read_path_string(pal::string_t &str)
+{
+ size_t size = read_path_length();
+ std::unique_ptr<uint8_t[]> buffer{ new uint8_t[size + 1] };
+ read(buffer.get(), size);
+ buffer[size] = 0; // null-terminator
+ pal::clr_palstring(reinterpret_cast<const char*>(buffer.get()), &str);
+}