fix: reject opening directories as files in ext2 and fat32, add mbrtowc to libc
This commit is contained in:
@@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MONTAUK_BUILD_NUMBER 182
|
#define MONTAUK_BUILD_NUMBER 184
|
||||||
|
|||||||
@@ -1202,6 +1202,13 @@ namespace Fs::Ext2 {
|
|||||||
Inode inode;
|
Inode inode;
|
||||||
if (!TraversePath(self, path, &inodeNum, &inode)) return -1;
|
if (!TraversePath(self, path, &inodeNum, &inode)) return -1;
|
||||||
|
|
||||||
|
// Directories are not openable as files, matching the ramdisk. A
|
||||||
|
// handle on one would fail every read/write anyway, and userspace
|
||||||
|
// stat() falls back to open() when it cannot get real metadata:
|
||||||
|
// succeeding here classified every directory as a regular file and
|
||||||
|
// GCC's include-path setup then rejected them as "not a directory".
|
||||||
|
if ((inode.i_mode & IMODE_TYPE_MASK) == IMODE_DIR) return -1;
|
||||||
|
|
||||||
for (int i = 0; i < MaxFilesPerInstance; i++) {
|
for (int i = 0; i < MaxFilesPerInstance; i++) {
|
||||||
if (!self.files[i].inUse) {
|
if (!self.files[i].inUse) {
|
||||||
self.files[i].inUse = true;
|
self.files[i].inUse = true;
|
||||||
|
|||||||
@@ -955,6 +955,10 @@ namespace Fs::Fat32 {
|
|||||||
ParsedEntry entry;
|
ParsedEntry entry;
|
||||||
if (!TraversePath(inst, path, &entry)) return -1;
|
if (!TraversePath(inst, path, &entry)) return -1;
|
||||||
|
|
||||||
|
// Directories are not openable as files; see the matching note in
|
||||||
|
// Ext2::OpenImpl (userspace stat() falls back to open()).
|
||||||
|
if ((entry.attributes & ATTR_DIRECTORY) != 0) return -1;
|
||||||
|
|
||||||
// Find a free file handle
|
// Find a free file handle
|
||||||
auto& self = g_instances[inst];
|
auto& self = g_instances[inst];
|
||||||
for (int i = 0; i < MaxFilesPerInstance; i++) {
|
for (int i = 0; i < MaxFilesPerInstance; i++) {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ typedef struct {
|
|||||||
/* Byte-oriented C locale only: one byte, one character. */
|
/* Byte-oriented C locale only: one byte, one character. */
|
||||||
size_t mbstowcs(wchar_t *dst, const char *src, size_t n);
|
size_t mbstowcs(wchar_t *dst, const char *src, size_t n);
|
||||||
int mblen(const char *s, size_t n);
|
int mblen(const char *s, size_t n);
|
||||||
|
size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
/* ========================================================================
|
/* ========================================================================
|
||||||
Raw syscall wrappers (C versions matching kernel ABI)
|
Raw syscall wrappers (C versions matching kernel ABI)
|
||||||
@@ -3622,6 +3623,20 @@ int mbtowc(wchar_t *pwc, const char *s, size_t n) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restartable form of mbtowc. The C locale carries no shift state, so ps is
|
||||||
|
ignored; binutils reaches for this once configure sees mbstate_t. */
|
||||||
|
size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) {
|
||||||
|
(void)ps;
|
||||||
|
if (s == NULL) return 0; /* query: the C locale is stateless */
|
||||||
|
if (n == 0) return (size_t)-2; /* incomplete: no bytes to examine */
|
||||||
|
if (*s == '\0') {
|
||||||
|
if (pwc != NULL) *pwc = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pwc != NULL) *pwc = (wchar_t)(unsigned char)*s;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int wctomb(char *s, wchar_t wc) {
|
int wctomb(char *s, wchar_t wc) {
|
||||||
if (s == NULL) return 0;
|
if (s == NULL) return 0;
|
||||||
*s = (char)wc;
|
*s = (char)wc;
|
||||||
|
|||||||
Reference in New Issue
Block a user