Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Address some feedback by @vitek-karas
Browse files Browse the repository at this point in the history
* Use spaces instead of tabs for indentation
* Fix trace messages
* Fix some rebasing problems
* Improve pal::get_temp_dir() on windows.
* Fix a few minor issues (function ordering etc)
* Read/Write file extraction in 8KB chunks
* Also fix a bug in the extractor for a similar issue.
* Rename bundle processor to bundle runner
  • Loading branch information
swaroop-sridhar committed Apr 12, 2019
1 parent 9c8df22 commit d181371
Show file tree
Hide file tree
Showing 12 changed files with 566 additions and 496 deletions.
67 changes: 34 additions & 33 deletions src/corehost/cli/bdl_file_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,50 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#ifdef FEATURE_APPHOST

#include "bdl_processor.h"
#include "pal.h"
#include "error_codes.h"
#include "trace.h"
#include "utils.h"

using namespace bundle;

bool file_entry_t::is_valid()
{
return data.offset > 0 && data.size > 0 &&
(file_type_t)data.type < file_type_t::END &&
data.path_length > 0 && data.path_length <= PATH_MAX;
return data.offset > 0 && data.size > 0 &&
(file_type_t)data.type < file_type_t::__last &&
data.path_length > 0 && data.path_length <= PATH_MAX;
}

file_entry_t* file_entry_t::read(FILE* bundle)
file_entry_t* file_entry_t::read(FILE* stream)
{
file_entry_t* entry = new file_entry_t();

// First read the fixed-sized portion of file-entry
bdl_processor_t::read(&entry->data, sizeof(entry->data), bundle);
if (!entry->is_valid())
{
trace::error(_X("Invalid FileEntry"));
throw StatusCode::BundleExtractionFailure;
}

// Read the relative-path, given its length
pal::string_t& path = entry->relative_path;
bdl_processor_t::read_string(path, entry->data.path_length, bundle);

// Fixup the relative-path to have current platform's directory separator.
if (bundle_dir_separator != DIR_SEPARATOR)
{
for(size_t pos = path.find(bundle_dir_separator);
pos != pal::string_t::npos;
pos = path.find(bundle_dir_separator, pos))
{
path[pos] = DIR_SEPARATOR;
}
}

return entry;
file_entry_t* entry = new file_entry_t();

// First read the fixed-sized portion of file-entry
bundle_runner_t::read(&entry->data, sizeof(entry->data), stream);
if (!entry->is_valid())
{
trace::error(_X("Failure processing application bundle; possible file corruption."));
trace::error(_X("Invalid FileEntry detected."));
throw StatusCode::BundleExtractionFailure;
}

// Read the relative-path, given its length
pal::string_t& path = entry->relative_path;
bundle_runner_t::read_string(path, entry->data.path_length, stream);

// Fixup the relative-path to have current platform's directory separator.
if (bundle_dir_separator != DIR_SEPARATOR)
{
for (size_t pos = path.find(bundle_dir_separator);
pos != pal::string_t::npos;
pos = path.find(bundle_dir_separator, pos))
{
path[pos] = DIR_SEPARATOR;
}
}

return entry;
}

#endif // FEATURE_APPHOST

79 changes: 38 additions & 41 deletions src/corehost/cli/bdl_file_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,52 @@
#ifndef __BDL_FILE_ENTRY_H__
#define __BDL_FILE_ENTRY_H__

#if FEATURE_APPHOST

#include <cstdint>
#include "bdl_file_type.h"
#include "pal.h"

#pragma pack(push, 1)

// FileEntry: Records information about embedded files.
//
// The bundle manifest records the following meta-data for each
// file embedded in the bundle:
// Fixed size portion (represented by file_entry_inner_t)
// - Offset
// - Size
// - File Entry Type
// - path-length (7-bit extension encoding, 1 Byte due to MAX_PATH)
// Variable Size portion
// - relative path ("path-length" Bytes)

class file_entry_t
namespace bundle
{
public:

// The inner structure represents the fields that can be
// read contiguously for every file_entry.
struct file_entry_inner_t
{
int64_t offset;
int64_t size;
file_type_t type;
int8_t path_length;
} data;
pal::string_t relative_path; // Path of an embedded file, relative to the extraction directory.

file_entry_t()
:data(), relative_path()
{
}

static file_entry_t* read(FILE* bundle);

private:
static const pal::char_t bundle_dir_separator = '/';
bool is_valid();
};
// FileEntry: Records information about embedded files.
//
// The bundle manifest records the following meta-data for each
// file embedded in the bundle:
// Fixed size portion (represented by file_entry_inner_t)
// - Offset
// - Size
// - File Entry Type
// - path-length (7-bit extension encoding, 1 Byte due to MAX_PATH)
// Variable Size portion
// - relative path ("path-length" Bytes)

class file_entry_t
{
public:

// The inner structure represents the fields that can be
// read contiguously for every file_entry.
#pragma pack(push, 1)
struct
{
int64_t offset;
int64_t size;
file_type_t type;
int8_t path_length;
} data;
#pragma pack(pop)
pal::string_t relative_path; // Path of an embedded file, relative to the extraction directory.

file_entry_t()
:data(), relative_path()
{
}

#endif // FEATURE_APPHOST
static file_entry_t* read(FILE* stream);

private:
static const pal::char_t bundle_dir_separator = '/';
bool is_valid();
};
}
#endif // __BDL_FILE_ENTRY_H__
37 changes: 18 additions & 19 deletions src/corehost/cli/bdl_file_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,27 @@
#ifndef __BDL_FILE_TYPE_H__
#define __BDL_FILE_TYPE_H__

#if FEATURE_APPHOST
#include <cstdint>

// FileType: Identifies the type of file embedded into the bundle.
//
// The bundler differentiates a few kinds of files via the manifest,
// with respect to the way in which they'll be used by the runtime.
//
// Currently all files are extracted out to the disk, but future
// implementations will process certain file_types directly from the bundle.

enum file_type_t : uint8_t
namespace bundle
{
assembly,
ready2run,
deps_json,
runtime_config_json,
extract,
END
};

// FileType: Identifies the type of file embedded into the bundle.
//
// The bundler differentiates a few kinds of files via the manifest,
// with respect to the way in which they'll be used by the runtime.
//
// Currently all files are extracted out to the disk, but future
// implementations will process certain file_types directly from the bundle.

#endif // FEATURE_APPHOST
enum file_type_t : uint8_t
{
assembly,
ready2run,
deps_json,
runtime_config_json,
extract,
__last
};
}

#endif // __BDL_FILE_TYPE_H__
109 changes: 56 additions & 53 deletions src/corehost/cli/bdl_manifest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,80 +2,83 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#ifdef FEATURE_APPHOST

#include "bdl_processor.h"
#include "pal.h"
#include "error_codes.h"
#include "trace.h"
#include "utils.h"

const char *manifest_footer_t::m_expected_signature = ".NetCoreBundle";
using namespace bundle;

bool manifest_footer_t::is_valid()
bool manifest_header_t::is_valid()
{
return header_offset > 0 &&
signature_length == 14 &&
strcmp(signature, m_expected_signature) == 0;
return m_data.major_version == m_current_major_version &&
m_data.minor_version == m_current_minor_version &&
m_data.num_embedded_files > 0 &&
m_data.bundle_id_length > 0 &&
m_data.bundle_id_length < PATH_MAX;
}

manifest_footer_t* manifest_footer_t::read(FILE* bundle)
manifest_header_t* manifest_header_t::read(FILE* stream)
{
manifest_footer_t* footer = new manifest_footer_t();

bdl_processor_t::read(footer, num_bytes_read(), bundle);

if (!footer->is_valid())
{
trace::info(_X("Manifest footer Invalid"));
throw StatusCode::AppHostExeNotBundle;
}

return footer;
manifest_header_t* header = new manifest_header_t();

// First read the fixed size portion of the header
bundle_runner_t::read(&header->m_data, sizeof(header->m_data), stream);
if (!header->is_valid())
{
trace::error(_X("Failure processing application bundle."));
trace::error(_X("Manifest header version compatibility check failed"));

throw StatusCode::BundleExtractionFailure;
}

// Next read the bundle-ID string, given its length
bundle_runner_t::read_string(header->m_bundle_id,
header->m_data.bundle_id_length, stream);

return header;
}

bool manifest_header_t::is_valid()
const char* manifest_footer_t::m_expected_signature = ".NetCoreBundle";

bool manifest_footer_t::is_valid()
{
return data.major_version == m_current_major_version &&
data.minor_version == m_current_minor_version &&
data.num_embedded_files > 0 &&
data.bundle_id_length > 0 && data.bundle_id_length < PATH_MAX;
return m_header_offset > 0 &&
m_signature_length == 14 &&
strcmp(m_signature, m_expected_signature) == 0;
}

manifest_header_t* manifest_header_t::read(FILE* bundle)
manifest_footer_t* manifest_footer_t::read(FILE* stream)
{
manifest_header_t* header = new manifest_header_t();

// First read the fixed size portion of the header
bdl_processor_t::read(&header->data, sizeof(header->data), bundle);
if (!header->is_valid())
{
trace::error(_X("Manifest header incompatible"));
throw StatusCode::BundleExtractionFailure;
}

// Next read the bundle-ID string, given its length
bdl_processor_t::read_string(header->bundle_id, header->data.bundle_id_length, bundle);

return header;
manifest_footer_t* footer = new manifest_footer_t();

bundle_runner_t::read(footer, num_bytes_read(), stream);

if (!footer->is_valid())
{
trace::info(_X("This executable is not recognized as a bundle."));

throw StatusCode::AppHostExeNotBundle;
}

return footer;
}

manifest_t* manifest_t::read(FILE* bundle, int32_t num_files)
manifest_t* manifest_t::read(FILE* stream, int32_t num_files)
{
manifest_t* manifest = new manifest_t();
manifest_t* manifest = new manifest_t();

for (int32_t i = 0; i < num_files; i++)
{
file_entry_t* entry = file_entry_t::read(bundle);
if (entry == nullptr)
{
return nullptr;
}
for (int32_t i = 0; i < num_files; i++)
{
file_entry_t* entry = file_entry_t::read(stream);
if (entry == nullptr)
{
return nullptr;
}

manifest->files.push_back(entry);
}
manifest->files.push_back(entry);
}

return manifest;
return manifest;
}

#endif // FEATURE_APPHOST
Loading

0 comments on commit d181371

Please sign in to comment.