authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-30 12:17:52+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-30 19:17:19-05:00
logcbfd66f68a5a390abcf99e8cc6923d056ee1e4fa
tree7459e16f28ca5c7647aba00207dec2cad662b856
parenta05150e92d5925f14591d96220de3bb341be1154

Don't crash when parsing invalid files


1 files changed, 15 insertions(+), 34 deletions(-)

src/zig_clang.cpp+15-34
......@@ -13,6 +13,7 @@
1313 * 3. Prevent C++ from infecting the rest of the project.
1414 */
1515#include "zig_clang.h"
16#include "list.hpp"
1617
1718#if __GNUC__ >= 8
1819#pragma GCC diagnostic push
......@@ -1947,35 +1948,28 @@ ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char
19471948 bool allow_pch_with_compiler_errors = false;
19481949 bool single_file_parse = false;
19491950 bool for_serialization = false;
1950 std::unique_ptr<clang::ASTUnit> *err_unit = new std::unique_ptr<clang::ASTUnit>();
1951 std::unique_ptr<clang::ASTUnit> err_unit;
19511952 clang::ASTUnit *ast_unit = clang::ASTUnit::LoadFromCommandLine(
19521953 args_begin, args_end,
19531954 pch_container_ops, diags, resources_path,
19541955 only_local_decls, clang::CaptureDiagsKind::All, clang::None, true, 0, clang::TU_Complete,
19551956 false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None,
1956 single_file_parse, user_files_are_volatile, for_serialization, clang::None, err_unit,
1957 single_file_parse, user_files_are_volatile, for_serialization, clang::None, &err_unit,
19571958 nullptr);
19581959
1960 *errors_len = 0;
1961
19591962 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
19601963 if (!ast_unit && !err_unit) {
19611964 return nullptr;
19621965 }
19631966
1964 if (diags->getClient()->getNumErrors() > 0) {
1965 if (ast_unit) {
1966 *err_unit = std::unique_ptr<clang::ASTUnit>(ast_unit);
1967 }
1967 if (diags->hasErrorOccurred()) {
1968 clang::ASTUnit *unit = ast_unit ? ast_unit : err_unit.get();
1969 ZigList<Stage2ErrorMsg> errors = {};
19681970
1969 size_t cap = 4;
1970 *errors_len = 0;
1971 *errors_ptr = reinterpret_cast<Stage2ErrorMsg*>(malloc(cap * sizeof(Stage2ErrorMsg)));
1972 if (*errors_ptr == nullptr) {
1973 return nullptr;
1974 }
1975
1976 for (clang::ASTUnit::stored_diag_iterator it = (*err_unit)->stored_diag_begin(),
1977 it_end = (*err_unit)->stored_diag_end();
1978 it != it_end; ++it)
1971 for (clang::ASTUnit::stored_diag_iterator it = unit->stored_diag_begin(),
1972 it_end = unit->stored_diag_end(); it != it_end; ++it)
19791973 {
19801974 switch (it->getLevel()) {
19811975 case clang::DiagnosticsEngine::Ignored:
......@@ -1987,21 +1981,10 @@ ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char
19871981 case clang::DiagnosticsEngine::Fatal:
19881982 break;
19891983 }
1984
19901985 llvm::StringRef msg_str_ref = it->getMessage();
1991 if (*errors_len >= cap) {
1992 cap *= 2;
1993 Stage2ErrorMsg *new_errors = reinterpret_cast<Stage2ErrorMsg *>(
1994 realloc(*errors_ptr, cap * sizeof(Stage2ErrorMsg)));
1995 if (new_errors == nullptr) {
1996 free(*errors_ptr);
1997 *errors_ptr = nullptr;
1998 *errors_len = 0;
1999 return nullptr;
2000 }
2001 *errors_ptr = new_errors;
2002 }
2003 Stage2ErrorMsg *msg = *errors_ptr + *errors_len;
2004 *errors_len += 1;
1986
1987 Stage2ErrorMsg *msg = errors.add_one();
20051988 msg->msg_ptr = (const char *)msg_str_ref.bytes_begin();
20061989 msg->msg_len = msg_str_ref.size();
20071990
......@@ -2027,10 +2010,8 @@ ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char
20272010 }
20282011 }
20292012
2030 if (*errors_len == 0) {
2031 free(*errors_ptr);
2032 *errors_ptr = nullptr;
2033 }
2013 *errors_ptr = errors.items;
2014 *errors_len = errors.length;
20342015
20352016 return nullptr;
20362017 }