mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
sproto bugfix
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
#include "msvcint.h"
|
#include "msvcint.h"
|
||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
@@ -172,7 +173,7 @@ encode(const struct sproto_arg *args) {
|
|||||||
// It's decimal.
|
// It's decimal.
|
||||||
lua_Number vn = lua_tonumber(L, -1);
|
lua_Number vn = lua_tonumber(L, -1);
|
||||||
// use 64bit integer for 32bit architecture.
|
// use 64bit integer for 32bit architecture.
|
||||||
v = (int64_t)(vn * args->extra + 0.5);
|
v = (int64_t)(round(vn * args->extra));
|
||||||
} else {
|
} else {
|
||||||
v = lua_tointegerx(L, -1, &isnum);
|
v = lua_tointegerx(L, -1, &isnum);
|
||||||
if(!isnum) {
|
if(!isnum) {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#define SIZEOF_LENGTH 4
|
#define SIZEOF_LENGTH 4
|
||||||
#define SIZEOF_HEADER 2
|
#define SIZEOF_HEADER 2
|
||||||
#define SIZEOF_FIELD 2
|
#define SIZEOF_FIELD 2
|
||||||
|
#define SIZEOF_INT64 ((int)sizeof(uint64_t))
|
||||||
|
#define SIZEOF_INT32 ((int)sizeof(uint32_t))
|
||||||
|
|
||||||
struct field {
|
struct field {
|
||||||
int tag;
|
int tag;
|
||||||
@@ -758,7 +760,7 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
|
|||||||
return NULL;
|
return NULL;
|
||||||
buffer++;
|
buffer++;
|
||||||
size--;
|
size--;
|
||||||
intlen = sizeof(uint32_t);
|
intlen = SIZEOF_INT32;
|
||||||
index = 1;
|
index = 1;
|
||||||
*noarray = 0;
|
*noarray = 0;
|
||||||
|
|
||||||
@@ -781,36 +783,38 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
|
|||||||
}
|
}
|
||||||
return NULL; // sz == SPROTO_CB_ERROR
|
return NULL; // sz == SPROTO_CB_ERROR
|
||||||
}
|
}
|
||||||
if (size < sizeof(uint64_t))
|
// notice: sizeof(uint64_t) is size_t (unsigned) , size may be negative. See issue #75
|
||||||
|
// so use MACRO SIZOF_INT64 instead
|
||||||
|
if (size < SIZEOF_INT64)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (sz == sizeof(uint32_t)) {
|
if (sz == SIZEOF_INT32) {
|
||||||
uint32_t v = u.u32;
|
uint32_t v = u.u32;
|
||||||
buffer[0] = v & 0xff;
|
buffer[0] = v & 0xff;
|
||||||
buffer[1] = (v >> 8) & 0xff;
|
buffer[1] = (v >> 8) & 0xff;
|
||||||
buffer[2] = (v >> 16) & 0xff;
|
buffer[2] = (v >> 16) & 0xff;
|
||||||
buffer[3] = (v >> 24) & 0xff;
|
buffer[3] = (v >> 24) & 0xff;
|
||||||
|
|
||||||
if (intlen == sizeof(uint64_t)) {
|
if (intlen == SIZEOF_INT64) {
|
||||||
uint32_to_uint64(v & 0x80000000, buffer);
|
uint32_to_uint64(v & 0x80000000, buffer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint64_t v;
|
uint64_t v;
|
||||||
if (sz != sizeof(uint64_t))
|
if (sz != SIZEOF_INT64)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (intlen == sizeof(uint32_t)) {
|
if (intlen == SIZEOF_INT32) {
|
||||||
int i;
|
int i;
|
||||||
// rearrange
|
// rearrange
|
||||||
size -= (index-1) * sizeof(uint32_t);
|
size -= (index-1) * SIZEOF_INT32;
|
||||||
if (size < sizeof(uint64_t))
|
if (size < SIZEOF_INT64)
|
||||||
return NULL;
|
return NULL;
|
||||||
buffer += (index-1) * sizeof(uint32_t);
|
buffer += (index-1) * SIZEOF_INT32;
|
||||||
for (i=index-2;i>=0;i--) {
|
for (i=index-2;i>=0;i--) {
|
||||||
int negative;
|
int negative;
|
||||||
memcpy(header+1+i*sizeof(uint64_t), header+1+i*sizeof(uint32_t), sizeof(uint32_t));
|
memcpy(header+1+i*SIZEOF_INT64, header+1+i*SIZEOF_INT32, SIZEOF_INT32);
|
||||||
negative = header[1+i*sizeof(uint64_t)+3] & 0x80;
|
negative = header[1+i*SIZEOF_INT64+3] & 0x80;
|
||||||
uint32_to_uint64(negative, header+1+i*sizeof(uint64_t));
|
uint32_to_uint64(negative, header+1+i*SIZEOF_INT64);
|
||||||
}
|
}
|
||||||
intlen = sizeof(uint64_t);
|
intlen = SIZEOF_INT64;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = u.u64;
|
v = u.u64;
|
||||||
@@ -956,14 +960,14 @@ sproto_encode(const struct sproto_type *st, void * buffer, int size, sproto_call
|
|||||||
return 0;
|
return 0;
|
||||||
return -1; // sz == SPROTO_CB_ERROR
|
return -1; // sz == SPROTO_CB_ERROR
|
||||||
}
|
}
|
||||||
if (sz == sizeof(uint32_t)) {
|
if (sz == SIZEOF_INT32) {
|
||||||
if (u.u32 < 0x7fff) {
|
if (u.u32 < 0x7fff) {
|
||||||
value = (u.u32+1) * 2;
|
value = (u.u32+1) * 2;
|
||||||
sz = 2; // sz can be any number > 0
|
sz = 2; // sz can be any number > 0
|
||||||
} else {
|
} else {
|
||||||
sz = encode_integer(u.u32, data, size);
|
sz = encode_integer(u.u32, data, size);
|
||||||
}
|
}
|
||||||
} else if (sz == sizeof(uint64_t)) {
|
} else if (sz == SIZEOF_INT64) {
|
||||||
sz= encode_uint64(u.u64, data, size);
|
sz= encode_uint64(u.u64, data, size);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1066,22 +1070,22 @@ decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
|
|||||||
int len = *stream;
|
int len = *stream;
|
||||||
++stream;
|
++stream;
|
||||||
--sz;
|
--sz;
|
||||||
if (len == sizeof(uint32_t)) {
|
if (len == SIZEOF_INT32) {
|
||||||
if (sz % sizeof(uint32_t) != 0)
|
if (sz % SIZEOF_INT32 != 0)
|
||||||
return -1;
|
return -1;
|
||||||
for (i=0;i<sz/sizeof(uint32_t);i++) {
|
for (i=0;i<sz/SIZEOF_INT32;i++) {
|
||||||
uint64_t value = expand64(todword(stream + i*sizeof(uint32_t)));
|
uint64_t value = expand64(todword(stream + i*SIZEOF_INT32));
|
||||||
args->index = i+1;
|
args->index = i+1;
|
||||||
args->value = &value;
|
args->value = &value;
|
||||||
args->length = sizeof(value);
|
args->length = sizeof(value);
|
||||||
cb(args);
|
cb(args);
|
||||||
}
|
}
|
||||||
} else if (len == sizeof(uint64_t)) {
|
} else if (len == SIZEOF_INT64) {
|
||||||
if (sz % sizeof(uint64_t) != 0)
|
if (sz % SIZEOF_INT64 != 0)
|
||||||
return -1;
|
return -1;
|
||||||
for (i=0;i<sz/sizeof(uint64_t);i++) {
|
for (i=0;i<sz/SIZEOF_INT64;i++) {
|
||||||
uint64_t low = todword(stream + i*sizeof(uint64_t));
|
uint64_t low = todword(stream + i*SIZEOF_INT64);
|
||||||
uint64_t hi = todword(stream + i*sizeof(uint64_t) + sizeof(uint32_t));
|
uint64_t hi = todword(stream + i*SIZEOF_INT64 + SIZEOF_INT32);
|
||||||
uint64_t value = low | hi << 32;
|
uint64_t value = low | hi << 32;
|
||||||
args->index = i+1;
|
args->index = i+1;
|
||||||
args->value = &value;
|
args->value = &value;
|
||||||
@@ -1175,16 +1179,16 @@ sproto_decode(const struct sproto_type *st, const void * data, int size, sproto_
|
|||||||
switch (f->type) {
|
switch (f->type) {
|
||||||
case SPROTO_TINTEGER: {
|
case SPROTO_TINTEGER: {
|
||||||
uint32_t sz = todword(currentdata);
|
uint32_t sz = todword(currentdata);
|
||||||
if (sz == sizeof(uint32_t)) {
|
if (sz == SIZEOF_INT32) {
|
||||||
uint64_t v = expand64(todword(currentdata + SIZEOF_LENGTH));
|
uint64_t v = expand64(todword(currentdata + SIZEOF_LENGTH));
|
||||||
args.value = &v;
|
args.value = &v;
|
||||||
args.length = sizeof(v);
|
args.length = sizeof(v);
|
||||||
cb(&args);
|
cb(&args);
|
||||||
} else if (sz != sizeof(uint64_t)) {
|
} else if (sz != SIZEOF_INT64) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
uint32_t low = todword(currentdata + SIZEOF_LENGTH);
|
uint32_t low = todword(currentdata + SIZEOF_LENGTH);
|
||||||
uint32_t hi = todword(currentdata + SIZEOF_LENGTH + sizeof(uint32_t));
|
uint32_t hi = todword(currentdata + SIZEOF_LENGTH + SIZEOF_INT32);
|
||||||
uint64_t v = (uint64_t)low | (uint64_t) hi << 32;
|
uint64_t v = (uint64_t)low | (uint64_t) hi << 32;
|
||||||
args.value = &v;
|
args.value = &v;
|
||||||
args.length = sizeof(v);
|
args.length = sizeof(v);
|
||||||
|
|||||||
Reference in New Issue
Block a user