- Bugfix: Corrected "off by one" error in the linenumber while parsing

resource.
- Bugfix: A segfault would occur if messagetables were parsed without
  memory options attached. Also added buffer-overflow safeguard while
  converting between byteorders.
- Finished remapping usertype resources onto standars types by tricking
  the parser into accepting a different token. The remapping can be
  disabled with a new commandline option '-m'.
- Resolved some warning about chars used as index on SGI O2 machine
  (the ctype isXXX() routines are macros there).
This commit is contained in:
Bertho Stultiens 2000-06-13 03:37:56 +00:00 committed by Alexandre Julliard
parent 8dd8d30b7d
commit 661a94033e
13 changed files with 216 additions and 78 deletions

View File

@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = user32
SOVERSION = 1.0
WRCEXTRA = -w16
WRCEXTRA = -w16 -m
ALTNAMES = user keyboard ddeml display mouse
SPEC_SRCS = \

View File

@ -1,3 +1,18 @@
---------------------------------------------------------------------------
Version 1.1.5 (12-Jun-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
- Bugfix: Corrected "off by one" error in the linenumber while parsing
resource.
- Bugfix: A segfault would occur if messagetables were parsed without
memory options attached. Also added buffer-overflow safeguard while
converting between byteorders.
- Finished remapping usertype resources onto standars types by tricking
the parser into accepting a different token. The remapping can be
disabled with a new commandline option '-m'.
- Resolved some warning about chars used as index on SGI O2 machine
(the ctype isXXX() routines are macros there).
---------------------------------------------------------------------------
Version 1.1.4 (07-Jun-2000)

View File

@ -1,4 +1,4 @@
Release 1.1.4 of wrc (07-Jun-2000), the wine resource compiler.
Release 1.1.5 of wrc (12-Jun-2000), the wine resource compiler.
See the file CHANGES for differences between the version and what has been
corrected in the current version.
@ -42,6 +42,7 @@ Usage: wrc [options...] [infile[.rc|.res]]
-I path Set include search dir to path (multiple -I allowed)
-l lan Set default language to lan (default is neutral {0, 0})
-L Leave case of embedded filenames as is
-m Do not remap numerical resource IDs
-n Do not generate .s file
-N Do not preprocess input
-o file Output to file (default is infile.[res|s|h]
@ -283,8 +284,6 @@ though):
different action for win32 and win16
- PUSHBOX control is unsupported. The MS docs use it plenty, but neither
MS' nor Borland's compiler supports it.
- Usertype resources with a type-clash are not handled correctly. These
should map onto other resources.
Reporting bugs and patches
--------------------------

View File

@ -237,7 +237,7 @@ static void dump_raw_data(raw_data_t *d)
{
printf("- ");
for(i = 0; i < 16; i++)
printf("%c", isprint(d->data[n-16+i]) ? d->data[n-16+i] : '.');
printf("%c", isprint(d->data[n-16+i] & 0xff) ? d->data[n-16+i] : '.');
printf("\n%08x: ", n);
}
else
@ -250,7 +250,7 @@ static void dump_raw_data(raw_data_t *d)
if(!j)
j = 16;
for(i = 0; i < j; i++)
printf("%c", isprint(d->data[n-j+i]) ? d->data[n-j+i] : '.');
printf("%c", isprint(d->data[n-j+i] & 0xff) ? d->data[n-j+i] : '.');
printf("\n");
}

View File

@ -1746,7 +1746,7 @@ char *prep_nid_for_label(name_id_t *nid)
buf[0] = '\0';
for(i = 0; *sptr && i < MAXNAMELEN; i++)
{
if((unsigned)*sptr < 0x80 && isprint((char)*sptr))
if((unsigned)*sptr < 0x80 && isprint(*sptr & 0xff))
buf[i] = *sptr++;
else
warning("Resourcename (str_unicode) contain unprintable characters or invalid translation, ignored");
@ -1761,7 +1761,7 @@ char *prep_nid_for_label(name_id_t *nid)
buf[0] = '\0';
for(i = 0; *cptr && i < MAXNAMELEN; i++)
{
if((unsigned)*cptr < 0x80 && isprint(*cptr))
if((unsigned)*cptr < 0x80 && isprint(*cptr & 0xff))
buf[i] = *cptr++;
else
warning("Resourcename (str_char) contain unprintable characters, ignored");

View File

@ -903,6 +903,7 @@ ver_words_t *add_ver_words(ver_words_t *w, int i)
return w;
}
#define MSGTAB_BAD_PTR(p, b, l, r) (((l) - ((char *)(p) - (char *)(b))) > (r))
messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
{
messagetable_t *msg = (messagetable_t *)xmalloc(sizeof(messagetable_t));
@ -912,8 +913,17 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
WORD hi;
msg->data = rd;
msg->memopt = *memopt;
free(memopt);
if(memopt)
{
msg->memopt = *memopt;
free(memopt);
}
else
msg->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
if(rd->size < sizeof(DWORD))
yyerror("Invalid messagetable, size too small");
nblk = *(DWORD *)rd->data;
lo = WRC_LOWORD(nblk);
hi = WRC_HIWORD(nblk);
@ -939,6 +949,8 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
{
msgtab_block_t *mbp = (msgtab_block_t *)&(((DWORD *)rd->data)[1]);
nblk = BYTESWAP_DWORD(nblk);
if(MSGTAB_BAD_PTR(mbp, rd->data, rd->size, nblk * sizeof(*mbp)))
yyerror("Messagetable's blocks are outside of defined data");
for(i = 0; i < nblk; i++)
{
msgtab_entry_t *mep;
@ -952,7 +964,9 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
{
mep->length = BYTESWAP_WORD(mep->length);
mep->flags = BYTESWAP_WORD(mep->flags);
if(mep->flags & 1)
if(MSGTAB_BAD_PTR(mep, rd->data, rd->size, mep->length))
yyerror("Messagetable's data for block %d, ID 0x%08lx is outside of defined data", (int)i, id);
if(mep->flags == 1) /* Docu says 'flags == 0x0001' for unicode */
{
WORD *wp = (WORD *)&mep[1];
int l = mep->length/2 - 2; /* Length included header */
@ -971,6 +985,7 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
return msg;
}
#undef MSGTAB_BAD_PTR
void copy_raw_data(raw_data_t *dst, raw_data_t *src, int offs, int len)
{

View File

@ -518,7 +518,7 @@ L\" {
char_number = 1;
}
yywarning("Unmatched text '%c' (0x%02x) YY_START=%d stripslevel=%d",
isprint(*yytext) ? *yytext : '.', *yytext, YY_START,stripslevel);
isprint(*yytext & 0xff) ? *yytext : '.', *yytext, YY_START,stripslevel);
}
%%

View File

@ -188,6 +188,7 @@ static toolbar_item_t *get_tlbr_buttons_head(toolbar_item_t *p, int *nitems);
static string_t *make_filename(string_t *s);
static resource_t *build_fontdirs(resource_t *tail);
static resource_t *build_fontdir(resource_t **fnt, int nfnt);
static int rsrcid_to_token(int lookahead);
%}
%union{
@ -411,7 +412,7 @@ resources
*/
preprocessor
: '#' { want_nl = 1; } tNUMBER tSTRING any_nums tNL {
line_number = $3 - 1;
line_number = $3;
input_name = $4->str.cstr;
/* fprintf(stderr, "Now at %s:%d\n", input_name, line_number); */
}
@ -437,18 +438,18 @@ cjunk : tTYPEDEF { strip_til_semicolon(); }
/* Parse top level resource definitions etc. */
resource
: nameid resource_definition {
$$ = $2;
: nameid usrcvt resource_definition {
$$ = $3;
if($$)
{
$$->name = $1;
if($1->type == name_ord)
{
chat("Got %s (%d)",get_typename($2),$1->name.i_name);
chat("Got %s (%d)",get_typename($3),$1->name.i_name);
}
else if($1->type == name_str)
{
chat("Got %s (%s)",get_typename($2),$1->name.s_name->str.cstr);
chat("Got %s (%s)",get_typename($3),$1->name.s_name->str.cstr);
}
}
}
@ -474,6 +475,13 @@ resource
}
;
/*
* Remapping of numerical resource types
* (see also comment of called function below)
*/
usrcvt : /* Empty */ { yychar = rsrcid_to_token(yychar); }
;
/*
* Get a valid name/id
*/
@ -662,48 +670,6 @@ dlginit : tDLGINIT loadmemopts file_raw { $$ = new_dlginit($3, $2); }
/* ------------------------------ UserType ------------------------------ */
userres : usertype loadmemopts file_raw {
if($1->type == name_ord)
{
switch($1->name.i_name)
{
case WRC_RT_CURSOR: /* Bad idea; cursors should generate directories */
case WRC_RT_ANICURSOR:
case WRC_RT_ICON:
case WRC_RT_ANIICON: /* Bad idea; icons should generate directories */
case WRC_RT_BITMAP:
case WRC_RT_FONT: /* Bad idea; fonts should generate directories */
case WRC_RT_FONTDIR:
case WRC_RT_RCDATA: /* This cannot be interpreted anyway */
case WRC_RT_MESSAGETABLE: /* This case is involked by mc.exe */
case WRC_RT_DLGINIT: /* No real layout available */
/* These should never be invoked because they have their own layout */
case WRC_RT_ACCELERATOR:
case WRC_RT_MENU:
case WRC_RT_DIALOG:
case WRC_RT_STRING:
case WRC_RT_TOOLBAR:
case WRC_RT_VERSION:
yywarning("Usertype uses special type-ID %d (wrc cannot yet re-interpret the data)", $1->name.i_name);
goto douser;
case WRC_RT_GROUP_CURSOR:
case WRC_RT_GROUP_ICON:
yywarning("Usertype uses reserved type-ID %d, which is auto-generated", $1->name.i_name);
goto douser;
case WRC_RT_DLGINCLUDE:
case WRC_RT_PLUGPLAY:
case WRC_RT_VXD:
case WRC_RT_HTML:
yywarning("Usertype uses reserved type-ID %d, which is not supported by wrc", $1->name.i_name);
default:
goto douser;
}
}
else
{
douser:
#ifdef WORDS_BIGENDIAN
if(pedantic && byteorder != WRC_BO_LITTLE)
#else
@ -712,7 +678,6 @@ userres : usertype loadmemopts file_raw {
yywarning("Byteordering is not little-endian and type cannot be interpreted");
$$ = new_user($1, $3, $2);
}
}
;
usertype: tNUMBER {
@ -2041,7 +2006,7 @@ byebye:
static name_id_t *convert_ctlclass(name_id_t *cls)
{
char *cc;
char *cc = NULL;
int iclass;
if(cls->type == name_ord)
@ -2213,7 +2178,7 @@ static event_t *add_string_event(string_t *key, int id, int flags, event_t *prev
if(key->type != str_char)
yyerror("Key code must be an ascii string");
if((flags & WRC_AF_VIRTKEY) && (!isupper(key->str.cstr[0]) && !isdigit(key->str.cstr[0])))
if((flags & WRC_AF_VIRTKEY) && (!isupper(key->str.cstr[0] & 0xff) && !isdigit(key->str.cstr[0] & 0xff)))
yyerror("VIRTKEY code is not equal to ascii value");
if(key->str.cstr[0] == '^' && (flags & WRC_AF_CONTROL) != 0)
@ -2821,3 +2786,131 @@ clean:
return lst;
}
/*
* This gets invoked to determine whether the next resource
* is to be of a standard-type (e.g. bitmaps etc.), or should
* be a user-type resource. This function is required because
* there is the _possibility_ of a lookahead token in the
* parser, which is generated from the "expr" state in the
* "nameid" parsing.
*
* The general resource format is:
* <identifier> <type> <flags> <resourcebody>
*
* The <identifier> can either be tIDENT or "expr". The latter
* will always generate a lookahead, which is the <type> of the
* resource to parse. Otherwise, we need to get a new token from
* the scanner to determine the next step.
*
* The problem arrises when <type> is numerical. This case should
* map onto default resource-types and be parsed as such instead
* of being mapped onto user-type resources.
*
* The trick lies in the fact that yacc (bison) doesn't care about
* intermediate changes of the lookahead while reducing a rule. We
* simply replace the lookahead with a token that will result in
* a shift to the appropriate rule for the specific resource-type.
*/
static int rsrcid_to_token(int lookahead)
{
int token;
char *type = "?";
/* Get a token if we don't have one yet */
if(lookahead == YYEMPTY)
lookahead = YYLEX;
/* Only numbers are possibly interesting */
switch(lookahead)
{
case tNUMBER:
case tLNUMBER:
break;
default:
return lookahead;
}
token = lookahead;
switch(yylval.num)
{
case WRC_RT_CURSOR:
type = "CURSOR";
token = tCURSOR;
break;
case WRC_RT_ICON:
type = "ICON";
token = tICON;
break;
case WRC_RT_BITMAP:
type = "BITMAP";
token = tBITMAP;
break;
case WRC_RT_FONT:
type = "FONT";
token = tFONT;
break;
case WRC_RT_FONTDIR:
type = "FONTDIR";
token = tFONTDIR;
break;
case WRC_RT_RCDATA:
type = "RCDATA";
token = tRCDATA;
break;
case WRC_RT_MESSAGETABLE:
type = "MESSAGETABLE";
token = tMESSAGETABLE;
break;
case WRC_RT_DLGINIT:
type = "DLGINIT";
token = tDLGINIT;
break;
case WRC_RT_ACCELERATOR:
type = "ACCELERATOR";
token = tACCELERATORS;
break;
case WRC_RT_MENU:
type = "MENU";
token = tMENU;
break;
case WRC_RT_DIALOG:
type = "DIALOG";
token = tDIALOG;
break;
case WRC_RT_VERSION:
type = "VERSION";
token = tVERSIONINFO;
break;
case WRC_RT_TOOLBAR:
type = "TOOLBAR";
token = tTOOLBAR;
break;
case WRC_RT_STRING:
type = "STRINGTABLE";
break;
case WRC_RT_ANICURSOR:
case WRC_RT_ANIICON:
case WRC_RT_GROUP_CURSOR:
case WRC_RT_GROUP_ICON:
yywarning("Usertype uses reserved type-ID %d, which is auto-generated", yylval.num);
return lookahead;
case WRC_RT_DLGINCLUDE:
case WRC_RT_PLUGPLAY:
case WRC_RT_VXD:
case WRC_RT_HTML:
yywarning("Usertype uses reserved type-ID %d, which is not supported by wrc", yylval.num);
default:
return lookahead;
}
if(remap)
return token;
else
yywarning("Usertype uses reserved type-ID %d, which is used by %s", yylval.num, type);
return lookahead;
}

View File

@ -656,7 +656,7 @@ includelogicentry_t *includelogiclist = NULL;
* This is a 'catch-all' rule to discover errors in the scanner
* in an orderly manner.
*/
<*>. seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext) ? *pptext : ' ', *pptext);
<*>. seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext & 0xff) ? *pptext : ' ', *pptext);
<<EOF>> {
YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
@ -954,7 +954,7 @@ static mtext_t *add_expand_text(mtext_t *mtp, macexpstackentry_t *mep, int *nnl)
/* Remove trailing whitespace from current expansion text */
while(curdef_idx)
{
if(isspace(curdef_text[curdef_idx-1]))
if(isspace(curdef_text[curdef_idx-1] & 0xff))
curdef_idx--;
else
break;
@ -968,7 +968,7 @@ static mtext_t *add_expand_text(mtext_t *mtp, macexpstackentry_t *mep, int *nnl)
n = curdef_idx - tag;
while(n)
{
if(isspace(*cptr))
if(isspace(*cptr & 0xff))
{
cptr++;
n--;
@ -1054,7 +1054,7 @@ static void expand_macro(macexpstackentry_t *mep)
/* Strip trailing whitespace from expansion */
for(k = curdef_idx, cptr = &curdef_text[curdef_idx-1]; k > 0; k--, cptr--)
{
if(!isspace(*cptr))
if(!isspace(*cptr & 0xff))
break;
}
@ -1069,7 +1069,7 @@ static void expand_macro(macexpstackentry_t *mep)
/* Strip leading whitespace from expansion */
for(n = 0, cptr = curdef_text; n < k; n++, cptr++)
{
if(!isspace(*cptr))
if(!isspace(*cptr & 0xff))
break;
}

View File

@ -569,7 +569,7 @@ static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp)
while(len)
{
/* FIXME: should delete space from head of string */
if(isspace(mtp->subst.text[len-1]))
if(isspace(mtp->subst.text[len-1] & 0xff))
mtp->subst.text[--len] = '\0';
else
break;
@ -588,7 +588,7 @@ static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp)
int len = strlen(tail->subst.text);
while(len)
{
if(isspace(tail->subst.text[len-1]))
if(isspace(tail->subst.text[len-1] & 0xff))
tail->subst.text[--len] = '\0';
else
break;

View File

@ -78,6 +78,7 @@ static char usage[] =
" -I path Set include search dir to path (multiple -I allowed)\n"
" -l lan Set default language to lan (default is neutral {0, 0})\n"
" -L Leave case of embedded filenames as is\n"
" -m Do not remap numerical resource IDs\n"
" -n Do not generate .s file\n"
" -N Do not preprocess input\n"
" -o file Output to file (default is infile.[res|s|h]\n"
@ -233,6 +234,11 @@ int preprocess_only = 0;
*/
int no_preprocess = 0;
/*
* Cleared when _not_ to remap resource types (-m option)
*/
int remap = 1;
char *output_name; /* The name given by the -o option */
char *input_name; /* The name given on the command-line */
char *header_name; /* The name given by the -H option */
@ -279,7 +285,7 @@ int main(int argc,char *argv[])
strcat(cmdline, " ");
}
while((optc = getopt(argc, argv, "a:AbB:cC:d:D:eEghH:I:l:LnNo:p:rstTVw:W")) != EOF)
while((optc = getopt(argc, argv, "a:AbB:cC:d:D:eEghH:I:l:LmnNo:p:rstTVw:W")) != EOF)
{
switch(optc)
{
@ -352,6 +358,9 @@ int main(int argc,char *argv[])
case 'L':
leave_case = 1;
break;
case 'm':
remap = 0;
break;
case 'n':
create_s = 0;
break;

View File

@ -16,8 +16,8 @@
#define WRC_MAJOR_VERSION 1
#define WRC_MINOR_VERSION 1
#define WRC_MICRO_VERSION 4
#define WRC_RELEASEDATE "(07-Jun-2000)"
#define WRC_MICRO_VERSION 5
#define WRC_RELEASEDATE "(09-Jun-2000)"
#define WRC_STRINGIZE(a) #a
#define WRC_VERSIONIZE(a,b,c) WRC_STRINGIZE(a) "." WRC_STRINGIZE(b) "." WRC_STRINGIZE(c)
@ -55,6 +55,7 @@ extern int leave_case;
extern int byteorder;
extern int preprocess_only;
extern int no_preprocess;
extern int remap;
extern char *prefix;
extern char *output_name;

View File

@ -1,4 +1,4 @@
.TH WRC 1 "June 07, 2000" "Version 1.1.4" "Wine Resource Compiler"
.TH WRC 1 "June 12, 2000" "Version 1.1.5" "Wine Resource Compiler"
.SH NAME
wrc \- Wine Resource Compiler
.SH SYNOPSIS
@ -105,6 +105,17 @@ Set default language to \fIlan\fR. Default is the neutral language 0
Leave case of embedded filenames as is. All filenames are converted to
lower case before they are attemped to be opened without this option.
.TP
.I \-m
Do not remap numerical resource type-IDs onto standard resources. This will
cause all numerical resource type\-IDs to be treated as user\-type resources
and will not be checked nor byte\-reversed. Without this option, resources
with, for example, type\-ID 2 are parsed as bitmaps and other type\-IDs will
map onto their respective standard type.
Use this option with caution because it can create problems when compiling for,
for example, big\-endian platforms. The \fI\-m\fR option is usefull for
source\-files that contain overlapping type\-IDs, or when the format of the
resource is not 100% compliant.
.TP
.I \-n
Do not generate an assembly outputfile (suppress generation of \fB.s\fR
file). Usefull if you are interested in a header file only.
@ -195,11 +206,6 @@ Fonts are parsed and generated, but there is no support for the
generation of the FONTDIR yet. The user must supply the FONTDIR
resource in the source to match the FONT resources.
.PP
Usertype resources that have a type-clash with other resources are not
handled correctly. These should map onto the builtin resources as much
as possible (especially icons, cursors and fonts because of directory
generation and everything else that would require byte-order swapping).
.PP
See the CHANGES and README.wrc files in the distribution for more
comments on bugs and fixes across the versions.
.SH AVAILABILITY