Skip to content

Commit

Permalink
Fix UB on memcpy and float conversion
Browse files Browse the repository at this point in the history
- add `memcpy_no_ub()` to allow copying 0 bytes from or to null pointers
- avoid converting out of range floats.
  • Loading branch information
chqrlie committed Mar 3, 2024
1 parent b289b81 commit 610b4c9
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 5 deletions.
7 changes: 7 additions & 0 deletions cutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define CUTILS_H

#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#define likely(x) __builtin_expect(!!(x), 1)
Expand Down Expand Up @@ -64,6 +65,12 @@ char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr);
int has_suffix(const char *str, const char *suffix);

/* Prevent UB when n == 0 and (src == NULL or dest == NULL) */
static inline void memcpy_no_ub(void *dest, const void *src, size_t n) {
if (n)
memcpy(dest, src, n);
}

static inline int max_int(int a, int b)
{
if (a > b)
Expand Down
11 changes: 6 additions & 5 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -33390,8 +33390,8 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd)
}
} else {
b->vardefs = (void *)((uint8_t*)b + vardefs_offset);
memcpy(b->vardefs, fd->args, fd->arg_count * sizeof(fd->args[0]));
memcpy(b->vardefs + fd->arg_count, fd->vars, fd->var_count * sizeof(fd->vars[0]));
memcpy_no_ub(b->vardefs, fd->args, fd->arg_count * sizeof(fd->args[0]));
memcpy_no_ub(b->vardefs + fd->arg_count, fd->vars, fd->var_count * sizeof(fd->vars[0]));
}
b->var_count = fd->var_count;
b->arg_count = fd->arg_count;
Expand Down Expand Up @@ -53999,9 +53999,10 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val,
} else
if (tag == JS_TAG_FLOAT64) {
d = JS_VALUE_GET_FLOAT64(argv[0]);
// XXX: should fix UB
v64 = d;
is_int = (v64 == d);
if (d >= INT64_MIN && d < 0x1p63) {
v64 = d;
is_int = (v64 == d);
}
} else if (tag == JS_TAG_BIG_INT) {
JSBigFloat *p1 = JS_VALUE_GET_PTR(argv[0]);

Expand Down

0 comments on commit 610b4c9

Please sign in to comment.