Check C API structure sizes before copying values to C++ classes (fixes issue #3238)

This commit is contained in:
Sergey Markelov 2021-12-14 14:37:54 -07:00 committed by Marshall Greenblatt
parent db9298fd3e
commit 5c0895e27f
5 changed files with 49 additions and 1 deletions

View File

@ -112,6 +112,7 @@
'libcef_dll/resource.h', 'libcef_dll/resource.h',
'libcef_dll/shutdown_checker.cc', 'libcef_dll/shutdown_checker.cc',
'libcef_dll/shutdown_checker.h', 'libcef_dll/shutdown_checker.h',
'libcef_dll/template_util.h',
'libcef_dll/transfer_util.cc', 'libcef_dll/transfer_util.cc',
'libcef_dll/transfer_util.h', 'libcef_dll/transfer_util.h',
'libcef_dll/wrapper_types.h', 'libcef_dll/wrapper_types.h',
@ -138,6 +139,7 @@
'libcef_dll/ctocpp/ctocpp_scoped.h', 'libcef_dll/ctocpp/ctocpp_scoped.h',
'libcef_dll/shutdown_checker.cc', 'libcef_dll/shutdown_checker.cc',
'libcef_dll/shutdown_checker.h', 'libcef_dll/shutdown_checker.h',
'libcef_dll/template_util.h',
'libcef_dll/transfer_util.cc', 'libcef_dll/transfer_util.cc',
'libcef_dll/transfer_util.h', 'libcef_dll/transfer_util.h',
'libcef_dll/wrapper_types.h', 'libcef_dll/wrapper_types.h',

View File

@ -113,7 +113,7 @@ template <typename T>
struct SupportsToString<T, decltype(void(std::declval<T>().ToString()))> struct SupportsToString<T, decltype(void(std::declval<T>().ToString()))>
: std::true_type {}; : std::true_type {};
// Used to detech whether the given type is an iterator. This is normally used // Used to detect whether the given type is an iterator. This is normally used
// with std::enable_if to provide disambiguation for functions that take // with std::enable_if to provide disambiguation for functions that take
// templatzed iterators as input. // templatzed iterators as input.
template <typename T, typename = void> template <typename T, typename = void>

View File

@ -0,0 +1,37 @@
// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_DLL_TEMPLATE_UTIL_H_
#define CEF_LIBCEF_DLL_TEMPLATE_UTIL_H_
#pragma once
#include <type_traits>
namespace template_util {
// Used to detect whether the given C struct has a size_t size field or has a
// base field and a base field has a size field.
template <typename T, typename = void>
struct HasValidSize {
bool operator()(const T*) { return true; }
};
template <typename T>
struct HasValidSize<
T,
typename std::enable_if_t<std::is_same<decltype(T::size), size_t>::value>> {
bool operator()(const T* s) { return s->size == sizeof(*s); }
};
template <typename T>
struct HasValidSize<T, decltype(void(T::base.size))> {
bool operator()(const T* s) { return s->base.size == sizeof(*s); }
};
template <typename T>
inline bool has_valid_size(const T* s) {
return HasValidSize<T>()(s);
}
} // namespace template_util
#endif // CEF_LIBCEF_DLL_TEMPLATE_UTIL_H_

View File

@ -266,6 +266,9 @@ def format_translation_includes(header, body):
if body.find('cef_api_hash(') > 0: if body.find('cef_api_hash(') > 0:
result += '#include "include/cef_api_hash.h"\n' result += '#include "include/cef_api_hash.h"\n'
if body.find('template_util::has_valid_size(') > 0:
result += '#include "libcef_dll/template_util.h"\n'
# identify what CppToC classes are being used # identify what CppToC classes are being used
p = re.compile('([A-Za-z0-9_]{1,})CppToC') p = re.compile('([A-Za-z0-9_]{1,})CppToC')
list = sorted(set(p.findall(body))) list = sorted(set(p.findall(body)))

View File

@ -117,6 +117,12 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
'\n DCHECK('+arg_name+');'\ '\n DCHECK('+arg_name+');'\
'\n if (!'+arg_name+')'\ '\n if (!'+arg_name+')'\
'\n return'+retval_default+';' '\n return'+retval_default+';'
if arg_type == 'struct_byref_const' or arg_type == 'struct_byref':
result +=\
'\n if (!template_util::has_valid_size('+arg_name+')) {'\
'\n NOTREACHED() << "invalid '+arg_name+'->[base.]size";'\
'\n return'+retval_default+';'\
'\n }'
elif arg_type == 'simple_vec_byref' or arg_type == 'bool_vec_byref' or \ elif arg_type == 'simple_vec_byref' or arg_type == 'bool_vec_byref' or \
arg_type == 'refptr_vec_same_byref' or arg_type == 'refptr_vec_diff_byref' or \ arg_type == 'refptr_vec_same_byref' or arg_type == 'refptr_vec_diff_byref' or \
arg_type == 'ownptr_vec_same_byref' or arg_type == 'ownptr_vec_diff_byref' or \ arg_type == 'ownptr_vec_same_byref' or arg_type == 'ownptr_vec_diff_byref' or \