fix an issue that calling Touch() right before file deletion causes use-after-free
This commit is contained in:
parent
3a4d801f95
commit
f6be39f719
8
main.cc
8
main.cc
@ -206,10 +206,11 @@ class Env final : public nf7::Env {
|
||||
}
|
||||
}
|
||||
|
||||
void Handle(const nf7::File::Event& e) noexcept override
|
||||
nf7::File* Handle(const nf7::File::Event& e) noexcept override
|
||||
try {
|
||||
// trigger File::Handle()
|
||||
GetFileOrThrow(e.id).Handle(e);
|
||||
auto& f = GetFileOrThrow(e.id);
|
||||
f.Handle(e);
|
||||
|
||||
// trigger file watcher
|
||||
auto itr = watchers_map_.find(e.id);
|
||||
@ -219,7 +220,10 @@ class Env final : public nf7::Env {
|
||||
|
||||
// trigger global watcher
|
||||
for (auto w : watchers_map_[0]) w->Handle(e);
|
||||
|
||||
return &f;
|
||||
} catch (nf7::ExpiredException&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Exit() noexcept override {
|
||||
|
9
nf7.cc
9
nf7.cc
@ -105,11 +105,12 @@ void File::Touch() noexcept {
|
||||
if (std::exchange(touch_, true)) {
|
||||
return;
|
||||
}
|
||||
env().ExecMain(std::make_shared<nf7::GenericContext>(*this), [this]() {
|
||||
if (id()) {
|
||||
env().Handle( {.id = id(), .type = Event::kUpdate});
|
||||
}
|
||||
env().ExecSub(
|
||||
std::make_shared<nf7::GenericContext>(*this),
|
||||
[this, &env = env(), fid = id()]() {
|
||||
if (env.Handle({ .id = fid, .type = nf7::File::Event::kUpdate })) {
|
||||
touch_ = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
File& File::FindOrThrow(std::string_view name) const {
|
||||
|
3
nf7.hh
3
nf7.hh
@ -288,7 +288,8 @@ class Env {
|
||||
virtual void Save() noexcept = 0;
|
||||
virtual void Throw(std::exception_ptr&&) noexcept = 0;
|
||||
|
||||
virtual void Handle(const File::Event&) noexcept = 0;
|
||||
// returns the target file if alive
|
||||
virtual nf7::File* Handle(const File::Event&) noexcept = 0;
|
||||
|
||||
virtual File* GetFile(File::Id) const noexcept = 0;
|
||||
File& GetFileOrThrow(File::Id) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user