Skip to content

Fix big endian serialization #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 2, 2024
Merged
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
3 changes: 0 additions & 3 deletions cutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
#include <stdlib.h>
#include <inttypes.h>

/* set if CPU is big endian */
#undef WORDS_BIGENDIAN

#if defined(_MSC_VER)
#include <windows.h>
#include <winsock2.h>
Expand Down
13 changes: 10 additions & 3 deletions libregexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2595,7 +2595,7 @@ const char *lre_get_groupnames(const uint8_t *bc_buf)
void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped)
{
uint8_t *p, *pe;
uint32_t n, r;
uint32_t n, r, nw;

p = buf;
if (len < RE_HEADER_LEN)
Expand Down Expand Up @@ -2630,16 +2630,23 @@ void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped)
case REOP_save_reset: // has two 8 bit arguments
break;
case REOP_range32: // variable length
for (r = 3 + 4 * get_u16(&p[1]); n < r; n += 4)
nw = get_u16(&p[1]); // number of pairs of uint32_t
if (is_byte_swapped)
n = bswap16(n);
for (r = 3 + 8 * nw; n < r; n += 4)
inplace_bswap32(&p[n]);
goto doswap16;
case REOP_range: // variable length
for (r = 3 + 2 * get_u16(&p[1]); n < r; n += 2)
nw = get_u16(&p[1]); // number of pairs of uint16_t
if (is_byte_swapped)
n = bswap16(n);
for (r = 3 + 4 * nw; n < r; n += 2)
inplace_bswap16(&p[n]);
goto doswap16;
default:
doswap16:
inplace_bswap16(&p[1]);
break;
}
break;
case 5:
Expand Down
62 changes: 30 additions & 32 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -32217,6 +32217,7 @@ static const char * const bc_tag_str[] = {
"TypedArray",
"ArrayBuffer",
"SharedArrayBuffer",
"RegExp",
"Date",
"ObjectValue",
"ObjectReference",
Expand Down Expand Up @@ -32505,20 +32506,14 @@ static int JS_WriteBigInt(BCWriterState *s, JSValue obj)
bc_put_leb128(s, len);
/* always saved in byte based little endian representation */
for(j = 0; j < n1; j++) {
dbuf_putc(&s->dbuf, v >> (j * 8));
bc_put_u8(s, v >> (j * 8));
}
for(; i < a->len; i++) {
limb_t v = a->tab[i];
#if LIMB_BITS == 32
#ifdef WORDS_BIGENDIAN
v = bswap32(v);
#endif
dbuf_put_u32(&s->dbuf, v);
bc_put_u32(s, v);
#else
#ifdef WORDS_BIGENDIAN
v = bswap64(v);
#endif
dbuf_put_u64(&s->dbuf, v);
bc_put_u64(s, v);
#endif
}
}
Expand Down Expand Up @@ -33110,33 +33105,45 @@ static int bc_get_u8(BCReaderState *s, uint8_t *pval)

static int bc_get_u16(BCReaderState *s, uint16_t *pval)
{
uint16_t v;
if (unlikely(s->buf_end - s->ptr < 2)) {
*pval = 0; /* avoid warning */
return bc_read_error_end(s);
}
*pval = get_u16(s->ptr);
v = get_u16(s->ptr);
if (is_be())
v = bswap16(v);
*pval = v;
s->ptr += 2;
return 0;
}

static __maybe_unused int bc_get_u32(BCReaderState *s, uint32_t *pval)
{
uint32_t v;
if (unlikely(s->buf_end - s->ptr < 4)) {
*pval = 0; /* avoid warning */
return bc_read_error_end(s);
}
*pval = get_u32(s->ptr);
v = get_u32(s->ptr);
if (is_be())
v = bswap32(v);
*pval = v;
s->ptr += 4;
return 0;
}

static int bc_get_u64(BCReaderState *s, uint64_t *pval)
{
uint64_t v;
if (unlikely(s->buf_end - s->ptr < 8)) {
*pval = 0; /* avoid warning */
return bc_read_error_end(s);
}
*pval = get_u64(s->ptr);
v = get_u64(s->ptr);
if (is_be())
v = bswap64(v);
*pval = v;
s->ptr += 8;
return 0;
}
Expand Down Expand Up @@ -33279,6 +33286,9 @@ static int JS_ReadFunctionBytecode(BCReaderState *s, JSFunctionBytecode *b,
return -1;
b->byte_code_buf = bc_buf;

if (is_be())
bc_byte_swap(bc_buf, bc_len);

pos = 0;
while (pos < bc_len) {
op = bc_buf[pos];
Expand Down Expand Up @@ -33373,15 +33383,9 @@ static JSValue JS_ReadBigInt(BCReaderState *s)
#if LIMB_BITS == 32
if (bc_get_u32(s, &v))
goto fail;
#ifdef WORDS_BIGENDIAN
v = bswap32(v);
#endif
#else
if (bc_get_u64(s, &v))
goto fail;
#ifdef WORDS_BIGENDIAN
v = bswap64(v);
#endif
#endif
a->tab[i] = v;
}
Expand Down Expand Up @@ -50410,7 +50414,8 @@ static JSValue js_dataview_getValue(JSContext *ctx,
{
JSTypedArray *ta;
JSArrayBuffer *abuf;
int is_swap, size;
BOOL littleEndian, is_swap;
int size;
uint8_t *ptr;
uint32_t v;
uint64_t pos;
Expand All @@ -50421,12 +50426,8 @@ static JSValue js_dataview_getValue(JSContext *ctx,
size = 1 << typed_array_size_log2(class_id);
if (JS_ToIndex(ctx, &pos, argv[0]))
return JS_EXCEPTION;
is_swap = FALSE;
if (argc > 1)
is_swap = JS_ToBool(ctx, argv[1]);
#ifndef WORDS_BIGENDIAN
is_swap ^= 1;
#endif
littleEndian = argc > 1 && JS_ToBool(ctx, argv[1]);
is_swap = littleEndian ^ !is_be();
abuf = ta->buffer->u.array_buffer;
if (abuf->detached)
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
Expand Down Expand Up @@ -50512,7 +50513,8 @@ static JSValue js_dataview_setValue(JSContext *ctx,
{
JSTypedArray *ta;
JSArrayBuffer *abuf;
int is_swap, size;
BOOL littleEndian, is_swap;
Copy link
Contributor

Choose a reason for hiding this comment

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

I know it's nitpicking but for consistency I would suggest calling it little_endian.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I used littleEndian for consistency with the ECMA document, otherwise I would definitely use little_endian.

int size;
uint8_t *ptr;
uint64_t v64;
uint32_t v;
Expand Down Expand Up @@ -50552,12 +50554,8 @@ static JSValue js_dataview_setValue(JSContext *ctx,
v64 = u.u64;
}
}
is_swap = FALSE;
if (argc > 2)
is_swap = JS_ToBool(ctx, argv[2]);
#ifndef WORDS_BIGENDIAN
is_swap ^= 1;
#endif
littleEndian = argc > 2 && JS_ToBool(ctx, argv[2]);
is_swap = littleEndian ^ !is_be();
abuf = ta->buffer->u.array_buffer;
if (abuf->detached)
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
Expand Down