added some error checks for error literals and smptr literals
This commit is contained in:
parent
de0715e302
commit
22127d384f
@ -83,6 +83,8 @@ static char* synerrstr[] =
|
||||
"wrong character literal",
|
||||
"invalid numeric literal",
|
||||
"out of integer range",
|
||||
"wrong error literal",
|
||||
"wrong smptr literal",
|
||||
|
||||
"sudden end of input",
|
||||
"( expected",
|
||||
|
51
lib/hcl.h
51
lib/hcl.h
@ -94,6 +94,8 @@ enum hcl_synerrnum_t
|
||||
HCL_SYNERR_CHARLIT, /* wrong character literal */
|
||||
HCL_SYNERR_RADNUMLIT , /* invalid numeric literal with radix */
|
||||
HCL_SYNERR_INTRANGE, /* integer range error */
|
||||
HCL_SYNERR_ERRORLIT, /* wrong error literal */
|
||||
HCL_SYNERR_SMPTRLIT, /* wrong smptr literal */
|
||||
|
||||
HCL_SYNERR_EOF, /* sudden end of input */
|
||||
HCL_SYNERR_LPAREN, /* ( expected */
|
||||
@ -236,38 +238,6 @@ typedef struct hcl_obj_word_t* hcl_oop_word_t;
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* OOP encoding
|
||||
* An object pointer(OOP) is an ordinary pointer value to an object.
|
||||
* but some simple numeric values are also encoded into OOP using a simple
|
||||
* bit-shifting and masking.
|
||||
*
|
||||
* A real OOP is stored without any bit-shifting while a non-OOP value encoded
|
||||
* in an OOP is bit-shifted to the left by 2 and the 2 least-significant bits
|
||||
* are set to 1 or 2.
|
||||
*
|
||||
* This scheme works because the object allocators aligns the object size to
|
||||
* a multiple of sizeof(hcl_oop_t). This way, the 2 least-significant bits
|
||||
* of a real OOP are always 0s.
|
||||
*/
|
||||
|
||||
#define HCL_OOP_TAG_BITS 2
|
||||
#define HCL_OOP_TAG_SMOOI 1
|
||||
#define HCL_OOP_TAG_CHAR 2
|
||||
|
||||
#define HCL_OOP_IS_NUMERIC(oop) (((hcl_oow_t)oop) & (HCL_OOP_TAG_SMOOI | HCL_OOP_TAG_CHAR))
|
||||
#define HCL_OOP_IS_POINTER(oop) (!HCL_OOP_IS_NUMERIC(oop))
|
||||
#define HCL_OOP_GET_TAG(oop) (((hcl_oow_t)oop) & HCL_LBMASK(hcl_oow_t, HCL_OOP_TAG_BITS))
|
||||
|
||||
#define HCL_OOP_IS_SMOOI(oop) (((hcl_ooi_t)oop) & HCL_OOP_TAG_SMOOI)
|
||||
#define HCL_OOP_IS_CHAR(oop) (((hcl_oow_t)oop) & HCL_OOP_TAG_CHAR)
|
||||
#define HCL_SMOOI_TO_OOP(num) ((hcl_oop_t)((((hcl_ooi_t)(num)) << HCL_OOP_TAG_BITS) | HCL_OOP_TAG_SMOOI))
|
||||
#define HCL_OOP_TO_SMOOI(oop) (((hcl_ooi_t)oop) >> HCL_OOP_TAG_BITS)
|
||||
#define HCL_CHAR_TO_OOP(num) ((hcl_oop_t)((((hcl_oow_t)(num)) << HCL_OOP_TAG_BITS) | HCL_OOP_TAG_CHAR))
|
||||
#define HCL_OOP_TO_CHAR(oop) (((hcl_oow_t)oop) >> HCL_OOP_TAG_BITS)
|
||||
|
||||
#else
|
||||
/*
|
||||
* OOP encoding
|
||||
* An object pointer(OOP) is an ordinary pointer value to an object.
|
||||
@ -327,8 +297,6 @@ typedef struct hcl_obj_word_t* hcl_oop_word_t;
|
||||
#define HCL_OOP_TO_ERROR(oop) (((hcl_oow_t)oop) >> (HCL_OOP_TAG_BITS_LO + HCL_OOP_TAG_BITS_LO))
|
||||
#define HCL_ERROR_TO_OOP(num) ((hcl_oop_t)((((hcl_oow_t)(num)) << (HCL_OOP_TAG_BITS_LO + HCL_OOP_TAG_BITS_LO)) | HCL_OOP_TAG_ERROR))
|
||||
|
||||
#endif
|
||||
|
||||
/* SMOOI takes up 62 bit on a 64-bit architecture and 30 bits
|
||||
* on a 32-bit architecture. The absolute value takes up 61 bits and 29 bits
|
||||
* respectively for the 1 sign bit. */
|
||||
@ -341,6 +309,21 @@ typedef struct hcl_obj_word_t* hcl_oop_word_t;
|
||||
#define HCL_SMOOI_MIN (-HCL_SMOOI_MAX)
|
||||
#define HCL_IN_SMOOI_RANGE(ooi) ((ooi) >= HCL_SMOOI_MIN && (ooi) <= HCL_SMOOI_MAX)
|
||||
|
||||
|
||||
/* SMPTR is a special value which has been devised to encode an address value
|
||||
* whose low HCL_OOP_TAG_BITS_LO bits are 0. its class is SmallPointer. A pointer
|
||||
* returned by most of system functions would be aligned to the pointer size.
|
||||
* you can use the followings macros when converting such a pointer without loss. */
|
||||
#define HCL_IN_SMPTR_RANGE(ptr) ((((hcl_oow_t)ptr) & HCL_LBMASK(hcl_oow_t, HCL_OOP_TAG_BITS_LO)) == 0)
|
||||
|
||||
#define HCL_CHAR_BITS (HCL_OOI_BITS - HCL_OOP_TAG_BITS_LO - HCL_OOP_TAG_BITS_HI)
|
||||
#define HCL_CHAR_MIN 0
|
||||
#define HCL_CHAR_MAX (~((hcl_oow_t)0) >> (HCL_OOP_TAG_BITS_LO + HCL_OOP_TAG_BITS_HI))
|
||||
|
||||
#define HCL_ERROR_BITS (HCL_OOI_BITS - HCL_OOP_TAG_BITS_LO - HCL_OOP_TAG_BITS_HI)
|
||||
#define HCL_ERROR_MIN 0
|
||||
#define HCL_ERROR_MAX (~((hcl_oow_t)0) >> (HCL_OOP_TAG_BITS_LO + HCL_OOP_TAG_BITS_HI))
|
||||
|
||||
/* TODO: There are untested code where smint is converted to hcl_oow_t.
|
||||
* for example, the spec making macro treats the number as hcl_oow_t instead of hcl_ooi_t.
|
||||
* as of this writing, i skip testing that part with the spec value exceeding HCL_SMOOI_MAX.
|
||||
|
@ -191,7 +191,7 @@ next:
|
||||
}
|
||||
else if (HCL_OOP_IS_SMPTR(obj))
|
||||
{
|
||||
if (outbfmt(hcl, mask, "#\\p%zu", (hcl_oow_t)HCL_OOP_TO_SMPTR(obj)) <= -1) return -1;
|
||||
if (outbfmt(hcl, mask, "#\\p%zX", (hcl_oow_t)HCL_OOP_TO_SMPTR(obj)) <= -1) return -1;
|
||||
goto done;
|
||||
}
|
||||
else if (HCL_OOP_IS_ERROR(obj))
|
||||
|
21
lib/read.c
21
lib/read.c
@ -823,12 +823,13 @@ static int get_sharp_token (hcl_t* hcl)
|
||||
|
||||
if (TOKEN_NAME_LEN(hcl) >= 4)
|
||||
{
|
||||
if (hcl->c->tok.name.ptr[2] == 'p')
|
||||
if (TOKEN_NAME_CHAR(hcl, 2) == 'P' || TOKEN_NAME_CHAR(hcl, 2) == 'p')
|
||||
{
|
||||
SET_TOKEN_TYPE (hcl, HCL_IOTOK_SMPTRLIT);
|
||||
goto hexcharlit;
|
||||
}
|
||||
else if (hcl->c->tok.name.ptr[2] == 'x' || hcl->c->tok.name.ptr[2] == 'u')
|
||||
else if (TOKEN_NAME_CHAR(hcl, 2) == 'X' || TOKEN_NAME_CHAR(hcl, 2) == 'x' ||
|
||||
TOKEN_NAME_CHAR(hcl, 2) == 'U' || TOKEN_NAME_CHAR(hcl, 2) == 'u')
|
||||
{
|
||||
hcl_oow_t i;
|
||||
|
||||
@ -845,7 +846,7 @@ static int get_sharp_token (hcl_t* hcl)
|
||||
c = c * 16 + CHAR_TO_NUM(hcl->c->tok.name.ptr[i], 16); /* don't care if it is for 'p' */
|
||||
}
|
||||
}
|
||||
else if (hcl->c->tok.name.ptr[2] == 'e')
|
||||
else if (TOKEN_NAME_CHAR(hcl, 2) == 'E' || TOKEN_NAME_CHAR(hcl, 2) == 'e')
|
||||
{
|
||||
hcl_oow_t i;
|
||||
for (i = 3; i < TOKEN_NAME_LEN(hcl); i++)
|
||||
@ -1756,7 +1757,6 @@ static int read_object (hcl_t* hcl)
|
||||
switch (TOKEN_TYPE(hcl))
|
||||
{
|
||||
default:
|
||||
HCL_ASSERT (hcl, !"should never happen - invalid token type");
|
||||
hcl_seterrbfmt (hcl, HCL_EINTERN, "invalid token encountered - %d %.*js",
|
||||
TOKEN_TYPE(hcl), TOKEN_NAME_LEN(hcl), TOKEN_NAME_PTR(hcl));
|
||||
return -1;
|
||||
@ -1960,6 +1960,13 @@ static int read_object (hcl_t* hcl)
|
||||
v = v * 16 + CHAR_TO_NUM(TOKEN_NAME_CHAR(hcl, i), 16);
|
||||
}
|
||||
|
||||
if (!HCL_IN_SMPTR_RANGE(v))
|
||||
{
|
||||
hcl_setsynerr (hcl, HCL_SYNERR_SMPTRLIT, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
obj = HCL_SMPTR_TO_OOP(v);
|
||||
break;
|
||||
}
|
||||
@ -1974,6 +1981,12 @@ static int read_object (hcl_t* hcl)
|
||||
{
|
||||
HCL_ASSERT (hcl, is_digitchar(TOKEN_NAME_CHAR(hcl, i)));
|
||||
v = v * 10 + CHAR_TO_NUM(TOKEN_NAME_CHAR(hcl, i), 10);
|
||||
|
||||
if (v > HCL_ERROR_MAX)
|
||||
{
|
||||
hcl_setsynerr (hcl, HCL_SYNERR_ERRORLIT, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
obj = HCL_ERROR_TO_OOP(v);
|
||||
|
Loading…
Reference in New Issue
Block a user