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:
return mk_succ(read());
}
throw_corrupted_file();
throw corrupted_stream_exception();
});
}
};
@ -247,7 +247,7 @@ public:
binder_info bi = read_binder_info(d);
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(),
[](deserializer & d, unsigned num, expr const * args) {
if (num != 1)
throw_corrupted_file();
throw corrupted_stream_exception();
name k;
d >> k;
return mk_annotation(k, args[0]);

View file

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

View file

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

View file

@ -293,7 +293,7 @@ static register_macro_deserializer_fn
resolve_macro_des_fn(g_resolve_opcode,
[](deserializer &, unsigned num, expr const * args) {
if (num != 3)
throw_corrupted_file();
throw corrupted_stream_exception();
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,
[](deserializer & d, unsigned num, expr const *) {
if (num != 0)
throw_corrupted_file();
throw corrupted_stream_exception();
std::string v = d.read_string();
return mk_string_macro(v);
});

View file

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

View file

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

View file

@ -27,9 +27,8 @@ void serializer_core::write_int(int i) {
#define BIG_BUFFER 1024
void throw_corrupted_file() {
throw exception("corrupted binary file");
}
corrupted_stream_exception::corrupted_stream_exception():
exception("corrupted binary file") {}
void serializer_core::write_double(double d) {
std::ostringstream out;
@ -49,7 +48,7 @@ std::string deserializer_core::read_string() {
if (c == 0)
break;
if (c == EOF)
throw_corrupted_file();
throw corrupted_stream_exception();
r += c;
}
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, 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>
serializer & write_list(serializer & s, list<T> const & ls) {

View file

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