[ruby/prism] Stat file first to check directory

https://github.com/ruby/prism/commit/4ed7de537b
This commit is contained in:
Kevin Newton 2024-09-13 15:18:14 -04:00 коммит произвёл git
Родитель f85efc9748
Коммит ddbd644001
3 изменённых файлов: 25 добавлений и 16 удалений

Просмотреть файл

@ -254,38 +254,45 @@ pm_string_file_init(pm_string_t *string, const char *filepath) {
*string = (pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = (size_t) file_size };
return PM_STRING_INIT_SUCCESS;
#elif defined(PRISM_HAS_FILESYSTEM)
FILE *file = fopen(filepath, "rb");
if (file == NULL) {
// Open the file for reading
int fd = open(filepath, O_RDONLY);
if (fd == -1) {
return PM_STRING_INIT_ERROR_GENERIC;
}
fseek(file, 0, SEEK_END);
long file_size = ftell(file);
if (file_size == -1) {
fclose(file);
// Stat the file to get the file size
struct stat sb;
if (fstat(fd, &sb) == -1) {
close(fd);
return PM_STRING_INIT_ERROR_GENERIC;
}
if (file_size == 0) {
fclose(file);
// Ensure it is a file and not a directory
if (S_ISDIR(sb.st_mode)) {
close(fd);
return PM_STRING_INIT_ERROR_DIRECTORY;
}
// Check the size to see if it's empty
size_t size = (size_t) sb.st_size;
if (size == 0) {
close(fd);
const uint8_t source[] = "";
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
return PM_STRING_INIT_SUCCESS;
}
size_t length = (size_t) file_size;
size_t length = (size_t) size;
uint8_t *source = xmalloc(length);
if (source == NULL) {
fclose(file);
close(fd);
return PM_STRING_INIT_ERROR_GENERIC;
}
fseek(file, 0, SEEK_SET);
size_t bytes_read = fread(source, length, 1, file);
fclose(file);
long bytes_read = (long) read(fd, source, length);
close(fd);
if (bytes_read != 1) {
if (bytes_read == -1) {
xfree(source);
return PM_STRING_INIT_ERROR_GENERIC;
}

Просмотреть файл

@ -22,6 +22,9 @@
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#elif defined(PRISM_HAS_FILESYSTEM)
#include <fcntl.h>
#include <sys/stat.h>
#endif
/**

Просмотреть файл

@ -87,7 +87,6 @@ module Prism
rescue SystemCallError => error
end
return if error.nil? || error.is_a?(Errno::ENOMEM)
assert_kind_of Errno::EISDIR, error
end