浏览代码

Prevent crash when we can't write to editor cache or config path

This can happen if users somehow got wrong user permissions assigned to
their Godot cache, config or data paths (e.g. `~/.config/godot`).

The error messages should give them a hint as to what the issue may be.

Fixes #33199.

There may be other situations that still lead to a crash, we need to
review all uses of `FileAccess::open` with `FileAccess::WRITE` mode to
ensure that proper pointer validation is done.

(cherry picked from commit 565f7183aab390986e678dfb909e2481e94e441f)
Rémi Verschelde 5 年之前
父节点
当前提交
5f314c54ff
共有 2 个文件被更改,包括 25 次插入10 次删除
  1. 11 6
      editor/editor_file_system.cpp
  2. 14 4
      editor/editor_resource_preview.cpp

+ 11 - 6
editor/editor_file_system.cpp

@@ -322,13 +322,14 @@ void EditorFileSystem::_save_filesystem_cache() {
 
 
 	FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE);
 	FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE);
 	if (f == NULL) {
 	if (f == NULL) {
-		ERR_PRINTS("Error writing fscache: " + fscache);
-	} else {
-		f->store_line(filesystem_settings_version_for_import);
-		_save_filesystem_cache(filesystem, f);
-		f->close();
-		memdelete(f);
+		ERR_EXPLAIN("Cannot create file '" + fscache + "'. Check user write permissions.");
+		ERR_FAIL();
 	}
 	}
+
+	f->store_line(filesystem_settings_version_for_import);
+	_save_filesystem_cache(filesystem, f);
+	f->close();
+	memdelete(f);
 }
 }
 
 
 void EditorFileSystem::_thread_func(void *_userdata) {
 void EditorFileSystem::_thread_func(void *_userdata) {
@@ -1370,6 +1371,10 @@ void EditorFileSystem::_save_late_updated_files() {
 	//files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file
 	//files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file
 	String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4");
 	String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4");
 	FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE);
 	FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE);
+	if (!f) {
+		ERR_EXPLAIN("Cannot create file '" + fscache + "'. Check user write permissions.");
+		ERR_FAIL();
+	}
 	for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) {
 	for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) {
 		f->store_line(E->get());
 		f->store_line(E->get());
 	}
 	}

+ 14 - 4
editor/editor_resource_preview.cpp

@@ -177,6 +177,10 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
 				ResourceSaver::save(cache_base + "_small.png", r_small_texture);
 				ResourceSaver::save(cache_base + "_small.png", r_small_texture);
 			}
 			}
 			FileAccess *f = FileAccess::open(cache_base + ".txt", FileAccess::WRITE);
 			FileAccess *f = FileAccess::open(cache_base + ".txt", FileAccess::WRITE);
+			if (!f) {
+				ERR_EXPLAIN("Cannot create file '" + cache_base + ".txt'. Check user write permissions.");
+				ERR_FAIL();
+			}
 			f->store_line(itos(thumbnail_size));
 			f->store_line(itos(thumbnail_size));
 			f->store_line(itos(has_small_texture));
 			f->store_line(itos(has_small_texture));
 			f->store_line(itos(FileAccess::get_modified_time(p_item.path)));
 			f->store_line(itos(FileAccess::get_modified_time(p_item.path)));
@@ -267,10 +271,16 @@ void EditorResourcePreview::_thread() {
 								//update modified time
 								//update modified time
 
 
 								f = FileAccess::open(file, FileAccess::WRITE);
 								f = FileAccess::open(file, FileAccess::WRITE);
-								f->store_line(itos(modtime));
-								f->store_line(itos(has_small_texture));
-								f->store_line(md5);
-								memdelete(f);
+								if (!f) {
+									// Not returning as this would leave the thread hanging and would require
+									// some proper cleanup/disabling of resource preview generation.
+									ERR_PRINTS("Cannot create file '" + file + "'. Check user write permissions.");
+								} else {
+									f->store_line(itos(modtime));
+									f->store_line(itos(has_small_texture));
+									f->store_line(md5);
+									memdelete(f);
+								}
 							}
 							}
 						} else {
 						} else {
 							memdelete(f);
 							memdelete(f);