Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/corehost/comhost/clsidmap.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,7 +100,7 @@ namespace
throw HResultException{ E_UNEXPECTED }; // This should never happen in Windows 7+

json_parser_t json;
if (!json.parse_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
if (!json.parse_fully_trusted_raw_data(reinterpret_cast<char*>(data), size, _X("<embedded .clsidmap>")))
{
trace::error(_X("Embedded .clsidmap is invalid.\n %s"), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand DownExpand Up@@ -178,7 +178,7 @@ namespace
return {};

json_parser_t json;
if (!json.parse_file(map_file_name))
if (!json.parse_fully_trusted_file(map_file_name))
{
trace::error(_X("File .clsidmap [%s] is invalid.\n %s"), map_file_name.c_str(), json.get_error_message().c_str());
throw HResultException{ StatusCode::InvalidConfigFile };
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/sdk_resolver.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -337,7 +337,7 @@ sdk_resolver::global_file_info sdk_resolver::parse_global_file(const pal::string
// After we're done parsing `global_file_path`, none of its contents will be referenced
// from the data private to json_parser_t; it's safe to declare it on the stack.
json_parser_t json;
if (!json.parse_file(global_file_path))
if (!json.parse_fully_trusted_file(global_file_path))
{
ret.error_message = json.get_error_message();
ret.state = global_file_info::state::invalid_json;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/hostpolicy/deps_format.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,7 +94,7 @@ deps_json_t::rid_fallback_graph_t deps_json_t::get_rid_fallback_graph(const pal:
return rid_fallback_graph;

json_parser_t json;
if (!json.parse_file(deps_path_local))
if (!json.parse_fully_trusted_file(deps_path_local))
return rid_fallback_graph;

populate_rid_fallback_graph(json.document(), rid_fallback_graph);
Expand DownExpand Up@@ -591,7 +591,7 @@ void deps_json_t::load(bool is_framework_dependent, std::function<void(const jso
}

json_parser_t json;
if (!json.parse_file(m_deps_file))
if (!json.parse_fully_trusted_file(m_deps_file))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_deps_file.c_str(), json.get_error_message().c_str());
return;
Expand Down
44 changes: 19 additions & 25 deletions src/native/corehost/json_parser.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@

namespace {

void get_line_column_from_offset(const char* data, uint64_t size, size_t offset, int *line, int *column)
void get_line_column_from_offset(const char* data, size_t size, size_t offset, int *line, int *column)
{
assert(offset <= size);

Expand All@@ -32,7 +32,7 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,
(*line)++;
*column = 1;
}
else if (data[i] == '\r' && data[i + 1] == '\n')
else if (data[i] == '\r' && (i + 1) < offset && data[i + 1] == '\n')
{
(*line)++;
*column = 1;
Expand All@@ -44,20 +44,20 @@ void get_line_column_from_offset(const char* data, uint64_t size, size_t offset,

} // empty namespace

bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t& context)
bool json_parser_t::parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context)
{
// This code assumes that the provided data is fully trusted; that is, that no portion
// of it has been provided by a hostile agent.

assert(data != nullptr);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag;
#ifdef _WIN32
// Can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings. m_document will store
// data in UTF-16 (with pal::char_t as the character type), but it
// has to know that data is encoded in UTF-8 to convert during parsing.
m_document.Parse<flags, rapidjson::UTF8<>>(data);
#else // _WIN32
m_document.ParseInsitu<flags>(data);
#endif // _WIN32

// Can't use in-situ parsing, as RapidJson requires a null-terminated string,
// and the provided data may not be null-terminated. The input data is always
// expected to be UTF-8 encoded; m_document is initialized with the appropriate
// encoding type for the underlying OS (UTF-16 on Windows; UTF-8 elsewhere).
m_document.Parse<flags, rapidjson::UTF8<>>(data, size);

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_document.HasParseError())
{
Expand All@@ -82,18 +82,19 @@ bool json_parser_t::parse_raw_data(char* data, int64_t size, const pal::string_t
return true;
}

bool json_parser_t::parse_file(const pal::string_t& path)
bool json_parser_t::parse_fully_trusted_file(const pal::string_t& path)
{
// This code assumes that the caller has checked that the file `path` exists
// either within the bundle, or as a real file on disk.
// either within the bundle, or as a real file on disk. It also assumes
// that the contents of the target file are fully trusted; that is, that no
// portion of its contents has been provided by a hostile agent.

assert(m_data == nullptr);
assert(m_bundle_location == nullptr);

if (bundle::info_t::is_single_file_bundle())
{
// Due to in-situ parsing on Linux,
// * The json file is mapped as copy-on-write.
// * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor.
// The mapping cannot be immediately released; it will be unmapped by the json_parser destructor.
Comment thread
GrabYourPitchforks marked this conversation as resolved.
m_data = bundle::info_t::config_t::map(path, m_bundle_location);

if (m_data != nullptr)
Expand All@@ -104,14 +105,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)

if (m_data == nullptr)
{
#ifdef _WIN32
// We can't use in-situ parsing on Windows, as JSON data is encoded in
// UTF-8 and the host expects wide strings.
// We do not need copy-on-write, so read-only mapping will be enough.
m_data = (char*)pal::mmap_read(path, &m_size);
#else // _WIN32
m_data = (char*)pal::mmap_copy_on_write(path, &m_size);
#endif // _WIN32

Comment thread
GrabYourPitchforks marked this conversation as resolved.
if (m_data == nullptr)
{
Expand All@@ -130,7 +124,7 @@ bool json_parser_t::parse_file(const pal::string_t& path)
data += 3;
}

return parse_raw_data(data, size, path);
return parse_fully_trusted_raw_data(data, size, path);
}

json_parser_t::~json_parser_t()
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/json_parser.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,8 +37,8 @@ class json_parser_t {
const document_t& document() const { return m_document; }
const pal::string_t& get_error_message() const { return m_parse_error; }

bool parse_raw_data(char* data, int64_t size, const pal::string_t& context);
bool parse_file(const pal::string_t& path);
bool parse_fully_trusted_raw_data(char* data, size_t size, const pal::string_t& context);
bool parse_fully_trusted_file(const pal::string_t& path);
Comment thread
GrabYourPitchforks marked this conversation as resolved.

json_parser_t()
: m_data(nullptr)
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/runtime_config.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -357,7 +357,7 @@ bool runtime_config_t::ensure_dev_config_parsed()
// runtimeconfig.dev.json is never bundled into the single-file app.
// So, only a file on disk is processed.
json_parser_t json;
if (!json.parse_file(m_dev_path))
if (!json.parse_fully_trusted_file(m_dev_path))
{
return false;
}
Expand DownExpand Up@@ -411,7 +411,7 @@ bool runtime_config_t::ensure_parsed()
}

json_parser_t json;
if (!json.parse_file(m_path))
if (!json.parse_fully_trusted_file(m_path))
{
trace::error(_X("Failed to parse file [%s]. %s"), m_path.c_str(), json.get_error_message().c_str());
return false;
Expand Down