Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/lib/evil/evil_stat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "evil_private.h"
#include <evil_api.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "evil_stat.h"

#define AT_SYMLINK_NOFOLLOW 0x01

EVIL_API int
fstatat(int dirfd, const char *pathname, struct stat *statbuf, int flags)
{
int r_fstatat;

if (pathname[1] == ':' && pathname[2] == '\\' || pathname[2] == '/' )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must check the buffer size before accessing it.

{
if (flags == AT_SYMLINK_NOFOLLOW)
r_fstatat = stat(pathname, statbuf);
else
r_fstatat = stat(pathname, statbuf);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the if both calls are exactly the same?

return r_fstatat;
}
else
{
char *pathbuf = NULL;
size_t pathbuf_size = 0;
DWORD copied = 0;
do
{
pathbuf_size += MAX_PATH;
pathbuf = realloc(pathbuf, pathbuf_size * sizeof(char));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The memory allocated here is never freed.

copied = GetModuleFileName(NULL, pathbuf, pathbuf_size);
} while (copied >= pathbuf_size);

int size_str;
for (size_str = strlen(pathbuf) -1; size_str >= 0; size_str --)
{
if (pathbuf[size_str] == '\\')
{
pathbuf[size_str + 1] = 0;
break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using _splitpath instead of a manual for loop?


size_str = strlen(pathbuf) + strlen(pathname);
char *path_complete = malloc(sizeof(char) * size_str + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The memory allocated here is never freed.

strcpy(path_complete, pathbuf);
strcat(path_complete, pathname);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if pathbuf doesn't end with a path separator?


if (flags == AT_SYMLINK_NOFOLLOW)
{
r_fstatat = stat(path_complete, statbuf);
}
else
{
r_fstatat = stat(path_complete, statbuf);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the if?

return r_fstatat;
}
}
30 changes: 30 additions & 0 deletions src/lib/evil/evil_stat.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
#ifndef __EVIL_STAT_H__
#define __EVIL_STAT_H__

#include <evil_windows.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <evil_macro_wrapper.h>
#include <evil_api.h>
#include <errno.h>

#ifndef _MSC_VER
# include <corecrt_io.h>
# include <corecrt.h>
#endif


typedef int mode_t ;
#ifndef stat64
# define stat64 _stat64
#endif

EVIL_API int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag);

// Missing definitions:
// Note: some pieces of code were based on LibreSSL-Portable's compat lib and
// adapted to EFL standards.

#ifdef _MSC_VER
# define S_IRWXU 0 /* RWX user */
# define S_IRUSR S_IREAD /* Read user */
Expand All @@ -17,6 +38,15 @@
# define S_IROTH 0 /* Read others */
# define S_IWOTH 0 /* Write others */
# define S_IXOTH 0 /* Execute others */

#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)

#endif

#endif
1 change: 1 addition & 0 deletions src/lib/evil/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ if target_machine.system() == 'windows'
'evil_unistd.c',
'evil_util.c',
'evil_private.h',
'evil_stat.c',
])

evil_header_src = [
Expand Down