feat(library/module): include name of corrupted .olean file

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-08-14 10:59:09 -07:00
parent d1c645977d
commit 0d97fff280
10 changed files with 63 additions and 49 deletions

View file

@ -63,7 +63,7 @@ public:
case level_kind::Succ: case level_kind::Succ:
return mk_succ(read()); return mk_succ(read());
} }
throw_corrupted_file(); throw corrupted_stream_exception();
}); });
} }
}; };
@ -247,7 +247,7 @@ public:
binder_info bi = read_binder_info(d); binder_info bi = read_binder_info(d);
return mk_local(n, pp_n, read(), bi); return mk_local(n, pp_n, read(), bi);
}} }}
throw_corrupted_file(); // LCOV_EXCL_LINE throw corrupted_stream_exception(); // LCOV_EXCL_LINE
}); });
} }
}; };
@ -363,7 +363,7 @@ static register_macro_deserializer_fn
annotation_des_fn(get_annotation_opcode(), annotation_des_fn(get_annotation_opcode(),
[](deserializer & d, unsigned num, expr const * args) { [](deserializer & d, unsigned num, expr const * args) {
if (num != 1) if (num != 1)
throw_corrupted_file(); throw corrupted_stream_exception();
name k; name k;
d >> k; d >> k;
return mk_annotation(k, args[0]); return mk_annotation(k, args[0]);

View file

@ -28,6 +28,10 @@ Author: Leonardo de Moura
#endif #endif
namespace lean { namespace lean {
corrupted_file_exception::corrupted_file_exception(std::string const & fname):
exception(sstream() << "failed to import '" << fname << "', file is corrupted") {
}
typedef std::pair<std::string, std::function<void(serializer &)>> writer; typedef std::pair<std::string, std::function<void(serializer &)>> writer;
struct module_ext : public environment_extension { struct module_ext : public environment_extension {
@ -229,47 +233,50 @@ struct import_modules_fn {
std::ifstream in(fname, std::ifstream::binary); std::ifstream in(fname, std::ifstream::binary);
if (!in.good()) if (!in.good())
throw exception(sstream() << "failed to open file '" << fname << "'"); throw exception(sstream() << "failed to open file '" << fname << "'");
deserializer d1(in); try {
std::string header; deserializer d1(in);
d1 >> header; std::string header;
if (header != g_olean_header) d1 >> header;
throw exception(sstream() << "file '" << fname << "' does not seem to be a valid object Lean file, invalid header"); if (header != g_olean_header)
unsigned major, minor, claimed_hash; throw exception(sstream() << "file '" << fname << "' does not seem to be a valid object Lean file, invalid header");
d1 >> major >> minor >> claimed_hash; unsigned major, minor, claimed_hash;
// Enforce version? d1 >> major >> minor >> claimed_hash;
// Enforce version?
unsigned num_imports = d1.read_unsigned(); unsigned num_imports = d1.read_unsigned();
buffer<module_name> imports; buffer<module_name> imports;
for (unsigned i = 0; i < num_imports; i++) for (unsigned i = 0; i < num_imports; i++)
imports.push_back(read_module_name(d1)); imports.push_back(read_module_name(d1));
unsigned code_size = d1.read_unsigned(); unsigned code_size = d1.read_unsigned();
std::vector<char> code(code_size); std::vector<char> code(code_size);
for (unsigned i = 0; i < code_size; i++) for (unsigned i = 0; i < code_size; i++)
code[i] = d1.read_char(); code[i] = d1.read_char();
unsigned computed_hash = hash(code_size, [&](unsigned i) { return code[i]; }); unsigned computed_hash = hash(code_size, [&](unsigned i) { return code[i]; });
if (claimed_hash != computed_hash) if (claimed_hash != computed_hash)
throw exception(sstream() << "file '" << fname << "' has been corrupted, checksum mismatch"); throw exception(sstream() << "file '" << fname << "' has been corrupted, checksum mismatch");
module_info_ptr r = std::make_shared<module_info>(); module_info_ptr r = std::make_shared<module_info>();
r->m_fname = fname; r->m_fname = fname;
r->m_counter = imports.size(); r->m_counter = imports.size();
r->m_module_idx = g_null_module_idx; r->m_module_idx = g_null_module_idx;
m_import_counter++; m_import_counter++;
std::string new_base = dirname(fname.c_str()); std::string new_base = dirname(fname.c_str());
std::swap(r->m_obj_code, code); std::swap(r->m_obj_code, code);
for (auto i : imports) { for (auto i : imports) {
auto d = load_module_file(new_base, i); auto d = load_module_file(new_base, i);
d->m_dependents.push_back(r); d->m_dependents.push_back(r);
}
m_module_info.insert(fname, r);
r->m_module_idx = m_next_module_idx++;
if (imports.empty())
add_import_module_task(r);
return r;
} catch (corrupted_stream_exception&) {
throw corrupted_file_exception(fname);
} }
m_module_info.insert(fname, r);
r->m_module_idx = m_next_module_idx++;
if (imports.empty())
add_import_module_task(r);
return r;
} }
void add_asynch_task(asynch_update_fn const & f) { void add_asynch_task(asynch_update_fn const & f) {

View file

@ -14,6 +14,11 @@ Author: Leonardo de Moura
#include "library/io_state.h" #include "library/io_state.h"
namespace lean { namespace lean {
class corrupted_file_exception : public exception {
public:
corrupted_file_exception(std::string const & fname);
};
class module_name { class module_name {
optional<unsigned> m_relative; optional<unsigned> m_relative;
name m_name; name m_name;

View file

@ -293,7 +293,7 @@ static register_macro_deserializer_fn
resolve_macro_des_fn(g_resolve_opcode, resolve_macro_des_fn(g_resolve_opcode,
[](deserializer &, unsigned num, expr const * args) { [](deserializer &, unsigned num, expr const * args) {
if (num != 3) if (num != 3)
throw_corrupted_file(); throw corrupted_stream_exception();
return mk_resolve_macro(args[0], args[1], args[2]); return mk_resolve_macro(args[0], args[1], args[2]);
}); });

View file

@ -92,7 +92,7 @@ static register_macro_deserializer_fn
string_macro_des_fn(g_string_opcode, string_macro_des_fn(g_string_opcode,
[](deserializer & d, unsigned num, expr const *) { [](deserializer & d, unsigned num, expr const *) {
if (num != 0) if (num != 0)
throw_corrupted_file(); throw corrupted_stream_exception();
std::string v = d.read_string(); std::string v = d.read_string();
return mk_string_macro(v); return mk_string_macro(v);
}); });

View file

@ -449,7 +449,7 @@ public:
name prefix = read(); name prefix = read();
return name(prefix, d.read_unsigned()); return name(prefix, d.read_unsigned());
}} }}
throw_corrupted_file(); throw corrupted_stream_exception();
}); });
} }
}; };

View file

@ -61,7 +61,7 @@ public:
} else { } else {
unsigned i = d.read_unsigned(); unsigned i = d.read_unsigned();
if (i >= m_table.size()) if (i >= m_table.size())
throw_corrupted_file(); throw corrupted_stream_exception();
return m_table[i]; return m_table[i];
} }
} }

View file

@ -27,9 +27,8 @@ void serializer_core::write_int(int i) {
#define BIG_BUFFER 1024 #define BIG_BUFFER 1024
void throw_corrupted_file() { corrupted_stream_exception::corrupted_stream_exception():
throw exception("corrupted binary file"); exception("corrupted binary file") {}
}
void serializer_core::write_double(double d) { void serializer_core::write_double(double d) {
std::ostringstream out; std::ostringstream out;
@ -49,7 +48,7 @@ std::string deserializer_core::read_string() {
if (c == 0) if (c == 0)
break; break;
if (c == EOF) if (c == EOF)
throw_corrupted_file(); throw corrupted_stream_exception();
r += c; r += c;
} }
return r; return r;

View file

@ -66,7 +66,10 @@ inline deserializer & operator>>(deserializer & d, char & c) { c = d.read_char()
inline deserializer & operator>>(deserializer & d, bool & b) { b = d.read_bool(); return d; } inline deserializer & operator>>(deserializer & d, bool & b) { b = d.read_bool(); return d; }
inline deserializer & operator>>(deserializer & d, double & b) { b = d.read_double(); return d; } inline deserializer & operator>>(deserializer & d, double & b) { b = d.read_double(); return d; }
[[ noreturn ]] void throw_corrupted_file(); class corrupted_stream_exception : public exception {
public:
corrupted_stream_exception();
};
template<typename T> template<typename T>
serializer & write_list(serializer & s, list<T> const & ls) { serializer & write_list(serializer & s, list<T> const & ls) {

View file

@ -357,7 +357,7 @@ public:
sexpr t = read(); sexpr t = read();
return sexpr(h, t); return sexpr(h, t);
}} }}
throw_corrupted_file(); throw corrupted_stream_exception();
}); });
} }
}; };