Commit 24b5050a authored by Bertho Stultiens's avatar Bertho Stultiens Committed by Alexandre Julliard

- Bugfix: Macro expansion of strings would assert an internal error

or a segfault due to a lacking '\0' in the expansion. - Bugfix: Prevent buffer overflow in reallocation of macro expansion buffers. - Bugfix: Wrc's version information was not passed as numerical to the preprocessor due to an error in the definition of the macro. - Relaxed the newline constraint in global LANGUAGE statements, which was introduced in version 1.1.3, so that some fancy preprocessor constructs can work. - Removed the gcc-style #line handling from the resource-parser to the resource-scanner so that it is possible to include files at any stage of the source, independent of the parser-state. - Bugfix: Stringtables were not correctly searched for duplicates because the language comparison disregarded the sublanguage. - Eliminated a repetitive warning when writing stringtables with zero length string entries. These are perfectly valid (but make no sense:-). Warnings are now only generated during parse in pedantic mode.
parent 7415c21e
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Version 1.1.6 (05-Jun-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
- Bugfix: Macro expansion of strings would assert an internal error
or a segfault due to a lacking '\0' in the expansion.
- Bugfix: Prevent buffer overflow in reallocation of macro expansion
buffers.
- Bugfix: Wrc's version information was not passed as numerical to the
preprocessor due to an error in the definition of the macro.
- Relaxed the newline constraint in global LANGUAGE statements, which
was introduced in version 1.1.3, so that some fancy preprocessor
constructs can work.
- Removed the gcc-style #line handling from the resource-parser to the
resource-scanner so that it is possible to include files at any stage
of the source, independent of the parser-state.
- Bugfix: Stringtables were not correctly searched for duplicates
because the language comparison disregarded the sublanguage.
- Eliminated a repetitive warning when writing stringtables with zero
length string entries. These are perfectly valid (but make no sense:-).
Warning are now only generated during parse in pedantic mode.
---------------------------------------------------------------------------
Version 1.1.5 (12-Jun-2000) Version 1.1.5 (12-Jun-2000)
Bertho Stultiens <bertho@akhphd.au.dk> Bertho Stultiens <bertho@akhphd.au.dk>
......
Release 1.1.5 of wrc (12-Jun-2000), the wine resource compiler. Release 1.1.6 of wrc (05-Jul-2000), the wine resource compiler.
See the file CHANGES for differences between the version and what has been See the file CHANGES for differences between the version and what has been
corrected in the current version. corrected in the current version.
...@@ -102,7 +102,7 @@ but not expanded properly. This will be corrected in the future. ...@@ -102,7 +102,7 @@ but not expanded properly. This will be corrected in the future.
The preprocessor handles the special defines and aditionally defines an The preprocessor handles the special defines and aditionally defines an
extra set of defines: extra set of defines:
Define | Value | Comment Define | Value | Comment
-----------+-------------------+--------------- ---------------+---------------+---------------
RC_INVOKED | 1 | Always defined RC_INVOKED | 1 | Always defined
__FLAT__ | 1 | Only defined if win32 compile __FLAT__ | 1 | Only defined if win32 compile
__WIN32__ | 1 | Only defined if win32 compile __WIN32__ | 1 | Only defined if win32 compile
...@@ -112,8 +112,8 @@ __TIME__ | "23:59:59" | Timestring of compilation ...@@ -112,8 +112,8 @@ __TIME__ | "23:59:59" | Timestring of compilation
__DATE__ | "May 1 2000" | Datestring of compilation __DATE__ | "May 1 2000" | Datestring of compilation
__WRC__  1 | Wrc's major version __WRC__  1 | Wrc's major version
__WRC_MINOR__ | 1 | Wrc's minor version __WRC_MINOR__ | 1 | Wrc's minor version
__WRC_MICRO__ | 0 | Wrc's minor version __WRC_MICRO__ | 6 | Wrc's minor version
__WRC_PATCH__ | 0 | Alias of __WRC_MICRO__ __WRC_PATCH__ | 6 | Alias of __WRC_MICRO__
Include-files are not read twice if they are protected with this scheme: Include-files are not read twice if they are protected with this scheme:
#ifndef SOME_DEFINE #ifndef SOME_DEFINE
......
...@@ -1416,7 +1416,7 @@ static res_t *stringtable2res(stringtable_t *stt) ...@@ -1416,7 +1416,7 @@ static res_t *stringtable2res(stringtable_t *stt)
restag = put_res_header(res, WRC_RT_STRING, NULL, &name, stt->memopt, win32 ? &(stt->lvc) : NULL); restag = put_res_header(res, WRC_RT_STRING, NULL, &name, stt->memopt, win32 ? &(stt->lvc) : NULL);
for(i = 0; i < stt->nentries; i++) for(i = 0; i < stt->nentries; i++)
{ {
if(stt->entries[i].str) if(stt->entries[i].str && stt->entries[i].str->size)
{ {
if(win32) if(win32)
put_word(res, stt->entries[i].str->size); put_word(res, stt->entries[i].str->size);
......
...@@ -65,6 +65,8 @@ ...@@ -65,6 +65,8 @@
%x pp_strips %x pp_strips
%x pp_stripp %x pp_stripp
%x pp_stripp_final %x pp_stripp_final
/* Set when scanning #line style directives */
%x pp_line
%option stack %option stack
%option never-interactive %option never-interactive
...@@ -291,6 +293,45 @@ static struct keyword *iskeyword(char *kw) ...@@ -291,6 +293,45 @@ static struct keyword *iskeyword(char *kw)
*/ */
%% %%
/* /*
* Catch the GCC-style line statements here and parse them.
* This has the advantage that you can #include at any
* stage in the resource file.
* The preprocessor generates line directives in the format:
* # <linenum> "filename" <codes>
*
* Codes can be a sequence of:
* - 1 start of new file
* - 2 returning to previous
* - 3 system header
* - 4 interpret as C-code
*
* 4 is not used and 1 mutually excludes 2
* Anyhow, we are not really interested in these at all
* because we only want to know the linenumber and
* filename.
*/
<INITIAL,pp_strips,pp_stripp>^{ws}*\#{ws}* yy_push_state(pp_line);
<pp_line>[^\n]* {
int lineno;
char *cptr;
char *fname;
yy_pop_state();
lineno = (int)strtol(yytext, &cptr, 10);
if(!lineno)
yyerror("Malformed '#...' line-directive; invalid linenumber");
fname = strchr(cptr, '"');
if(!fname)
yyerror("Malformed '#...' line-directive; missing filename");
fname++;
cptr = strchr(fname, '"');
if(!cptr)
yyerror("Malformed '#...' line-directive; missing terminating \"");
*cptr = '\0';
line_number = lineno - 1; /* We didn't read the newline */
input_name = xstrdup(fname);
}
/*
* Strip everything until a ';' taking * Strip everything until a ';' taking
* into account braces {} for structures, * into account braces {} for structures,
* classes and enums. * classes and enums.
......
...@@ -135,6 +135,8 @@ stringtable_t *tagstt; /* Stringtable tag. ...@@ -135,6 +135,8 @@ stringtable_t *tagstt; /* Stringtable tag.
stringtable_t *sttres; /* Stringtable resources. This holds the list of stringtable_t *sttres; /* Stringtable resources. This holds the list of
* stringtables with different lanuages * stringtables with different lanuages
*/ */
static int dont_want_id = 0; /* See language parsing for details */
/* Set to the current options of the currently scanning stringtable */ /* Set to the current options of the currently scanning stringtable */
static int *tagstt_memopt; static int *tagstt_memopt;
static characts_t *tagstt_characts; static characts_t *tagstt_characts;
...@@ -305,7 +307,7 @@ static int rsrcid_to_token(int lookahead); ...@@ -305,7 +307,7 @@ static int rsrcid_to_token(int lookahead);
%type <tlbarItems> toolbar_items %type <tlbarItems> toolbar_items
%type <dginit> dlginit %type <dginit> dlginit
%type <styles> optional_style_pair %type <styles> optional_style_pair
%type <num> any_num any_nums %type <num> any_num
%type <style> optional_style %type <style> optional_style
%type <style> style %type <style> style
%type <str> filename %type <str> filename
...@@ -388,39 +390,14 @@ resources ...@@ -388,39 +390,14 @@ resources
} }
else else
$$ = NULL; $$ = NULL;
if(!dont_want_id) /* See comments in language parsing below */
want_id = 1; want_id = 1;
dont_want_id = 0;
} }
| resources preprocessor { $$ = $1; want_id = 1; }
| resources cjunk { $$ = $1; want_id = 1; } | resources cjunk { $$ = $1; want_id = 1; }
; ;
/*
* The preprocessor generates line directives a la gcc
* in the format:
* # <linenum> "filename" <codes>
*
* Codes can be a sequence of:
* - 1 start of new file
* - 2 returning to previous
* - 3 system header
* - 4 interpret as C-code
*
* 4 is not used and 1 mutually excludes 2
* Anyhow, we are not really interested in these at all
* because we only want to know the linenumber and
* filename.
*/
preprocessor
: '#' { want_nl = 1; } tNUMBER tSTRING any_nums tNL {
line_number = $3;
input_name = $4->str.cstr;
/* fprintf(stderr, "Now at %s:%d\n", input_name, line_number); */
}
;
any_nums: any_num
| any_nums any_num
;
/* C ignore stuff */ /* C ignore stuff */
cjunk : tTYPEDEF { strip_til_semicolon(); } cjunk : tTYPEDEF { strip_til_semicolon(); }
...@@ -461,17 +438,40 @@ resource ...@@ -461,17 +438,40 @@ resource
$$ = NULL; $$ = NULL;
chat("Got STRINGTABLE"); chat("Got STRINGTABLE");
} }
| tLANGUAGE {want_nl = 1; } expr ',' expr tNL { | tLANGUAGE {want_nl = 1; } expr ',' expr {
/* We *NEED* the newline to delimit the expression. /* We *NEED* the newline to delimit the expression.
* Otherwise, we would not be able to set the next * Otherwise, we would not be able to set the next
* want_id anymore because of the token-lookahead. * want_id anymore because of the token-lookahead.
*
* However, we can test the lookahead-token for
* being "non-expression" type, in which case we
* continue. Fortunately, tNL is the only token that
* will break expression parsing and is implicitely
* void, so we just remove it. This scheme makes it
* possible to do some (not all) fancy preprocessor
* stuff.
* BTW, we also need to make sure that the next
* reduction of 'resources' above will *not* set
* want_id because we already have a lookahead that
* cannot be undone.
*/ */
if(yychar != YYEMPTY && yychar != tNL)
dont_want_id = 1;
if(yychar == tNL)
yychar = YYEMPTY;
else if(yychar == tIDENT)
yywarning("LANGUAGE statement not delimited with newline; next identifier might be wrong");
want_nl = 0; /* We don't want it anymore if we didn't get it */
if(!win32) if(!win32)
yywarning("LANGUAGE not supported in 16-bit mode"); yywarning("LANGUAGE not supported in 16-bit mode");
if(currentlanguage) if(currentlanguage)
free(currentlanguage); free(currentlanguage);
currentlanguage = new_language($3, $5); currentlanguage = new_language($3, $5);
$$ = NULL; $$ = NULL;
chat("Got LANGUAGE %d,%d (0x%04x)", $3, $5, ($5<<10) + $3);
} }
; ;
...@@ -1433,6 +1433,8 @@ strings : /* Empty */ { $$ = NULL; } ...@@ -1433,6 +1433,8 @@ strings : /* Empty */ { $$ = NULL; }
tagstt->entries[tagstt->nentries-1].version = tagstt_version; tagstt->entries[tagstt->nentries-1].version = tagstt_version;
tagstt->entries[tagstt->nentries-1].characts = tagstt_characts; tagstt->entries[tagstt->nentries-1].characts = tagstt_characts;
if(pedantic && !$4->size)
yywarning("Zero length strings make no sense");
if(!win32 && $4->size > 254) if(!win32 && $4->size > 254)
yyerror("Stringtable entry more than 254 characters"); yyerror("Stringtable entry more than 254 characters");
if(win32 && $4->size > 65534) /* Hmm..., does this happen? */ if(win32 && $4->size > 65534) /* Hmm..., does this happen? */
...@@ -2426,7 +2428,7 @@ static stringtable_t *find_stringtable(lvc_t *lvc) ...@@ -2426,7 +2428,7 @@ static stringtable_t *find_stringtable(lvc_t *lvc)
for(stt = sttres; stt; stt = stt->next) for(stt = sttres; stt; stt = stt->next)
{ {
if(stt->lvc.language->id == lvc->language->id if(stt->lvc.language->id == lvc->language->id
&& stt->lvc.language->id == lvc->language->id) && stt->lvc.language->sub == lvc->language->sub)
{ {
/* Found a table with the same language */ /* Found a table with the same language */
/* The version and characteristics are now handled /* The version and characteristics are now handled
......
...@@ -1307,13 +1307,14 @@ static void add_text_to_macro(char *text, int len) ...@@ -1307,13 +1307,14 @@ static void add_text_to_macro(char *text, int len)
assert(mep->ppp->expanding == 0); assert(mep->ppp->expanding == 0);
if(mep->curargalloc - mep->curargsize <= len) if(mep->curargalloc - mep->curargsize <= len+1) /* +1 for '\0' */
{ {
mep->curargalloc += ALLOCBLOCKSIZE; mep->curargalloc += MAX(ALLOCBLOCKSIZE, len+1);
mep->curarg = xrealloc(mep->curarg, mep->curargalloc * sizeof(mep->curarg[0])); mep->curarg = xrealloc(mep->curarg, mep->curargalloc * sizeof(mep->curarg[0]));
} }
memcpy(mep->curarg + mep->curargsize, text, len+1); /* +1 for '\0' */ memcpy(mep->curarg + mep->curargsize, text, len);
mep->curargsize += len; mep->curargsize += len;
mep->curarg[mep->curargsize] = '\0';
} }
static void macro_add_arg(int last) static void macro_add_arg(int last)
......
...@@ -561,10 +561,10 @@ int main(int argc,char *argv[]) ...@@ -561,10 +561,10 @@ int main(int argc,char *argv[])
pp_flex_debug = debuglevel & DEBUGLEVEL_PPLEX ? 1 : 0; pp_flex_debug = debuglevel & DEBUGLEVEL_PPLEX ? 1 : 0;
/* Set the default defined stuff */ /* Set the default defined stuff */
add_cmdline_define("__WRC__=" WRC_STRINGIZE(WRC_MAJOR_VERSION)); add_cmdline_define("__WRC__=" WRC_EXP_STRINGIZE(WRC_MAJOR_VERSION));
add_cmdline_define("__WRC_MINOR__=" WRC_STRINGIZE(WRC_MINOR_VERSION)); add_cmdline_define("__WRC_MINOR__=" WRC_EXP_STRINGIZE(WRC_MINOR_VERSION));
add_cmdline_define("__WRC_MICRO__=" WRC_STRINGIZE(WRC_MICRO_VERSION)); add_cmdline_define("__WRC_MICRO__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION));
add_cmdline_define("__WRC_PATCH__=" WRC_STRINGIZE(WRC_MICRO_VERSION)); add_cmdline_define("__WRC_PATCH__=" WRC_EXP_STRINGIZE(WRC_MICRO_VERSION));
add_cmdline_define("RC_INVOKED=1"); add_cmdline_define("RC_INVOKED=1");
......
...@@ -16,14 +16,18 @@ ...@@ -16,14 +16,18 @@
#define WRC_MAJOR_VERSION 1 #define WRC_MAJOR_VERSION 1
#define WRC_MINOR_VERSION 1 #define WRC_MINOR_VERSION 1
#define WRC_MICRO_VERSION 5 #define WRC_MICRO_VERSION 6
#define WRC_RELEASEDATE "(09-Jun-2000)" #define WRC_RELEASEDATE "(05-Jul-2000)"
#define WRC_STRINGIZE(a) #a #define WRC_STRINGIZE(a) #a
#define WRC_EXP_STRINGIZE(a) WRC_STRINGIZE(a)
#define WRC_VERSIONIZE(a,b,c) WRC_STRINGIZE(a) "." WRC_STRINGIZE(b) "." WRC_STRINGIZE(c) #define WRC_VERSIONIZE(a,b,c) WRC_STRINGIZE(a) "." WRC_STRINGIZE(b) "." WRC_STRINGIZE(c)
#define WRC_VERSION WRC_VERSIONIZE(WRC_MAJOR_VERSION, WRC_MINOR_VERSION, WRC_MICRO_VERSION) #define WRC_VERSION WRC_VERSIONIZE(WRC_MAJOR_VERSION, WRC_MINOR_VERSION, WRC_MICRO_VERSION)
#define WRC_FULLVERSION WRC_VERSION " " WRC_RELEASEDATE #define WRC_FULLVERSION WRC_VERSION " " WRC_RELEASEDATE
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
/* From wrc.c */ /* From wrc.c */
extern int debuglevel; extern int debuglevel;
......
.TH WRC 1 "June 12, 2000" "Version 1.1.5" "Wine Resource Compiler" .TH WRC 1 "July 05, 2000" "Version 1.1.6" "Wine Resource Compiler"
.SH NAME .SH NAME
wrc \- Wine Resource Compiler wrc \- Wine Resource Compiler
.SH SYNOPSIS .SH SYNOPSIS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment