11/*
22** {======================================================
33** Library for packing/unpacking structures.
4- ** $Id: struct.c,v 1.4 2012/07/04 18:54:29 roberto Exp $
4+ ** $Id: struct.c,v 1.7 2018/05/11 22:04:31 roberto Exp $
55** See Copyright Notice at the end of this file
66** =======================================================
77*/
1515** h/H - signed/unsigned short
1616** l/L - signed/unsigned long
1717** T - size_t
18- ** i/In - signed/unsigned integer with size ` n' (default is size of int)
19- ** cn - sequence of ` n' chars (from/to a string); when packing, n==0 means
18+ ** i/In - signed/unsigned integer with size ' n' (default is size of int)
19+ ** cn - sequence of ' n' chars (from/to a string); when packing, n==0 means
2020 the whole string; when unpacking, n==0 means use the previous
2121 read number as the string length
2222** s - zero-terminated string
@@ -89,14 +89,12 @@ typedef struct Header {
8989} Header ;
9090
9191
92- static int getnum (lua_State * L , const char * * fmt , int df ) {
92+ static int getnum (const char * * fmt , int df ) {
9393 if (!isdigit (* * fmt )) /* no number? */
9494 return df ; /* return default value */
9595 else {
9696 int a = 0 ;
9797 do {
98- if (a > (INT_MAX / 10 ) || a * 10 > (INT_MAX - (* * fmt - '0' )))
99- luaL_error (L , "integral size overflow" );
10098 a = a * 10 + * ((* fmt )++ ) - '0' ;
10199 } while (isdigit (* * fmt ));
102100 return a ;
@@ -117,9 +115,9 @@ static size_t optsize (lua_State *L, char opt, const char **fmt) {
117115 case 'f' : return sizeof (float );
118116 case 'd' : return sizeof (double );
119117 case 'x' : return 1 ;
120- case 'c' : return getnum (L , fmt , 1 );
118+ case 'c' : return getnum (fmt , 1 );
121119 case 'i' : case 'I' : {
122- int sz = getnum (L , fmt , sizeof (int ));
120+ int sz = getnum (fmt , sizeof (int ));
123121 if (sz > MAXINTSIZE )
124122 luaL_error (L , "integral size %d is larger than limit of %d" ,
125123 sz , MAXINTSIZE );
@@ -152,7 +150,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt,
152150 case '>' : h -> endian = BIG ; return ;
153151 case '<' : h -> endian = LITTLE ; return ;
154152 case '!' : {
155- int a = getnum (L , fmt , MAXALIGN );
153+ int a = getnum (fmt , MAXALIGN );
156154 if (!isp2 (a ))
157155 luaL_error (L , "alignment %d is not a power of 2" , a );
158156 h -> align = a ;
@@ -296,20 +294,21 @@ static int b_unpack (lua_State *L) {
296294 size_t ld ;
297295 const char * data = luaL_checklstring (L , 2 , & ld );
298296 size_t pos = luaL_optinteger (L , 3 , 1 ) - 1 ;
297+ int n = 0 ; /* number of results */
299298 defaultoptions (& h );
300- lua_settop (L , 2 );
301299 while (* fmt ) {
302300 int opt = * fmt ++ ;
303301 size_t size = optsize (L , opt , & fmt );
304302 pos += gettoalign (pos , & h , opt , size );
305303 luaL_argcheck (L , pos + size <= ld , 2 , "data string too short" );
306- luaL_checkstack (L , 1 , "too many results" );
304+ /* stack space for item + next position */
305+ luaL_checkstack (L , 2 , "too many results" );
307306 switch (opt ) {
308307 case 'b' : case 'B' : case 'h' : case 'H' :
309308 case 'l' : case 'L' : case 'T' : case 'i' : case 'I' : { /* integer types */
310309 int issigned = islower (opt );
311310 lua_Number res = getinteger (data + pos , h .endian , issigned , size );
312- lua_pushnumber (L , res );
311+ lua_pushnumber (L , res ); n ++ ;
313312 break ;
314313 }
315314 case 'x' : {
@@ -319,41 +318,42 @@ static int b_unpack (lua_State *L) {
319318 float f ;
320319 memcpy (& f , data + pos , size );
321320 correctbytes ((char * )& f , sizeof (f ), h .endian );
322- lua_pushnumber (L , f );
321+ lua_pushnumber (L , f ); n ++ ;
323322 break ;
324323 }
325324 case 'd' : {
326325 double d ;
327326 memcpy (& d , data + pos , size );
328327 correctbytes ((char * )& d , sizeof (d ), h .endian );
329- lua_pushnumber (L , d );
328+ lua_pushnumber (L , d ); n ++ ;
330329 break ;
331330 }
332331 case 'c' : {
333332 if (size == 0 ) {
334- if (!lua_isnumber (L , -1 ))
335- luaL_error (L , "format ` c0' needs a previous size" );
333+ if (n == 0 || !lua_isnumber (L , -1 ))
334+ luaL_error (L , "format ' c0' needs a previous size" );
336335 size = lua_tonumber (L , -1 );
337- lua_pop (L , 1 );
338- luaL_argcheck (L , pos + size <= ld , 2 , "data string too short" );
336+ lua_pop (L , 1 ); n -- ;
337+ luaL_argcheck (L , size <= ld && pos <= ld - size ,
338+ 2 , "data string too short" );
339339 }
340- lua_pushlstring (L , data + pos , size );
340+ lua_pushlstring (L , data + pos , size ); n ++ ;
341341 break ;
342342 }
343343 case 's' : {
344344 const char * e = (const char * )memchr (data + pos , '\0' , ld - pos );
345345 if (e == NULL )
346346 luaL_error (L , "unfinished string in data" );
347347 size = (e - (data + pos )) + 1 ;
348- lua_pushlstring (L , data + pos , size - 1 );
348+ lua_pushlstring (L , data + pos , size - 1 ); n ++ ;
349349 break ;
350350 }
351351 default : controloptions (L , opt , & fmt , & h );
352352 }
353353 pos += size ;
354354 }
355- lua_pushinteger (L , pos + 1 );
356- return lua_gettop ( L ) - 2 ;
355+ lua_pushinteger (L , pos + 1 ); /* next position */
356+ return n + 1 ;
357357}
358358
359359
@@ -399,7 +399,7 @@ LUALIB_API int luaopen_struct (lua_State *L) {
399399
400400
401401/******************************************************************************
402- * Copyright (C) 2010-2012 Lua.org, PUC-Rio. All rights reserved.
402+ * Copyright (C) 2010-2018 Lua.org, PUC-Rio. All rights reserved.
403403*
404404* Permission is hereby granted, free of charge, to any person obtaining
405405* a copy of this software and associated documentation files (the
0 commit comments