iopsys-feed/quickjs/patches/002-fix_std_loadFile.patch
Meng b179460524 quickjs: update to the latest version
Also add patch to fix std.loadFile issue for reading proc and sysfs.
2023-04-03 12:20:18 +00:00

126 lines
3.2 KiB
Diff

diff --git a/quickjs-libc.c b/quickjs-libc.c
index e180dd0..76182d2 100644
--- a/quickjs-libc.c
+++ b/quickjs-libc.c
@@ -358,12 +358,89 @@ fail:
return JS_EXCEPTION;
}
+// For reading files that are not seekable, per second answer from stackoverflow:
+// https://stackoverflow.com/questions/14002954/c-programming-how-to-read-the-whole-file-contents-into-a-buffer
+
+#define READALL_CHUNK 10*1024
+
+static int readall(FILE *f, JSContext *ctx, uint8_t **dataptr, size_t *sizeptr)
+{
+ uint8_t *data = NULL, *temp;
+ size_t size = 0;
+ size_t used = 0;
+ size_t n;
+
+ while (1) {
+ if (used + READALL_CHUNK + 1 > size) {
+ size = used + READALL_CHUNK + 1;
+
+ /* Overflow check. Some ANSI C compilers
+ may optimize this away, though. */
+ if (size <= used) {
+ if (ctx)
+ js_free(ctx, data);
+ else
+ free(data);
+ return -1;
+ }
+
+ if (ctx)
+ temp = js_realloc(ctx, data, size);
+ else
+ temp = realloc(data, size);
+
+ if (temp == NULL) {
+ if (ctx)
+ js_free(ctx, data);
+ else
+ free(data);
+ return -1;
+ }
+ data = temp;
+ }
+
+ n = fread(data + used, 1, READALL_CHUNK, f);
+ if (n == 0)
+ break;
+
+ used += n;
+ }
+
+ if (ferror(f)) {
+ if (ctx)
+ js_free(ctx, data);
+ else
+ free(data);
+ return -1;
+ }
+
+ if (ctx)
+ temp = js_realloc(ctx, data, used + 1);
+ else
+ temp = realloc(data, used + 1);
+
+ if (temp == NULL) {
+ if (ctx)
+ js_free(ctx, data);
+ else
+ free(data);
+ return -1;
+ }
+ data = temp;
+ data[used] = '\0';
+
+ *dataptr = data;
+ *sizeptr = used;
+
+ return 0;
+}
+
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
{
FILE *f;
uint8_t *buf;
size_t buf_len;
- long lret;
+ long lret = 0;
f = fopen(filename, "rb");
if (!f)
@@ -371,7 +448,7 @@ uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
if (fseek(f, 0, SEEK_END) < 0)
goto fail;
lret = ftell(f);
- if (lret < 0)
+ if (lret <= 0)
goto fail;
/* XXX: on Linux, ftell() return LONG_MAX for directories */
if (lret == LONG_MAX) {
@@ -387,13 +464,19 @@ uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename)
buf = malloc(buf_len + 1);
if (!buf)
goto fail;
- if (fread(buf, 1, buf_len, f) != buf_len) {
- errno = EIO;
+ buf_len = fread(buf, 1, buf_len, f);
+ if (ferror(f)) {
if (ctx)
js_free(ctx, buf);
else
free(buf);
fail:
+ // Files in proc and sysfs may not be seekable or may falsely
+ // appear to be of zero size. Try to read them in another way.
+ if (lret == 0 && readall(f, ctx, &buf, pbuf_len) == 0) {
+ fclose(f);
+ return buf;
+ }
fclose(f);
return NULL;
}