bin/118296: ndiscvt(8) can't parse a STRING WORD pattern when it
process a register key
Weongyo Jeong
weongyo.jeong at gmail.com
Tue Nov 27 18:10:02 PST 2007
>Number: 118296
>Category: bin
>Synopsis: ndiscvt(8) can't parse a STRING WORD pattern when it process a register key
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Nov 28 02:10:01 UTC 2007
>Closed-Date:
>Last-Modified:
>Originator: Weongyo Jeong
>Release: FreeBSD 7.0 CURRENT
>Organization:
CDNetworks
>Environment:
FreeBSD freebsd.weongyo.org 7.0-CURRENT FreeBSD 7.0-CURRENT #3: Sun Jun 24 21:47:30 KST 2007 weongyo at bsd.dev1.cdnetworks.co.kr:/usr/obj/usr/src/sys/GENERIC i386
>Description:
In current ndiscvt(8), it can only parse WORD or STRING separately and disallows a syntax like below:
HKLM,SOFTWARE\Mi,DEL_HKR_0000,0,"ENUM"%ZD1211B_50U_PNP%
So it make a syntax error when it parse some INF files. Attached patch is for supporting these.
>How-To-Repeat:
$ cat > t.inf
[UnZDRegistryUSB.reg]
HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\UNZD1211B%InterfaceType%,DEL_HKR_0000,0,"ENUM"%ZD1211B_50U_PNP%
^D
$ ndiscvt -i t.inf -s ZD11BUXP.SYS -o tmp.h
ndiscvt: line 2: %ZD1211B_50U_PNP%: syntax error.
>Fix:
Index: inf-parse.y
===================================================================
RCS file: /data/cvs/src/usr.sbin/ndiscvt/inf-parse.y,v
retrieving revision 1.2
diff -u -r1.2 inf-parse.y
--- inf-parse.y 2 Jan 2004 04:31:06 -0000 1.2
+++ inf-parse.y 27 Nov 2007 12:31:56 -0000
@@ -95,17 +95,12 @@
;
regkey
- : WORD
+ : WORD regkey
{ push_word($1); }
- | STRING
- { push_word($1); }
- | WORD COMMA regkey
- { push_word($1); }
- | STRING COMMA regkey
+ | STRING regkey
{ push_word($1); }
| COMMA regkey
{ push_word(NULL); }
- | COMMA
- { push_word(NULL); }
+ |
;
%%
Index: inf.c
===================================================================
RCS file: /data/cvs/src/usr.sbin/ndiscvt/inf.c,v
retrieving revision 1.16
diff -u -r1.16 inf.c
--- inf.c 15 May 2005 19:46:14 -0000 1.16
+++ inf.c 27 Nov 2007 12:31:56 -0000
@@ -67,6 +67,8 @@
static void dump_regvals (void);
static void dump_paramreg (const struct section *,
const struct reg *, int);
+static int regkey_getidx(int);
+static char * regkey_get(int);
static FILE *ofp;
@@ -736,6 +738,63 @@
return (0);
}
+static int
+regkey_getidx(int slot)
+{
+ int i, nullcount;
+
+ nullcount = 0;
+
+ if (slot <= 0)
+ return 0;
+
+ for (i = 0; i < idx; i++) {
+ if (words[i] != NULL)
+ continue;
+
+ nullcount++;
+ if (nullcount == slot)
+ break;
+ }
+
+ return i + 1;
+}
+
+static char *
+regkey_get(int rt)
+{
+ int i, start, slots;
+ char newbuf[256];
+
+ switch (rt) {
+ case REGKEY_SUBKEY:
+ start = regkey_getidx(3);
+ slots = regkey_getidx(4) - start - 1;
+ break;
+ case REGKEY_KEY:
+ start = regkey_getidx(2);
+ slots = regkey_getidx(3) - start - 1;
+ break;
+ case REGKEY_FLAGS:
+ start = regkey_getidx(1);
+ slots = regkey_getidx(2) - start - 1;
+ break;
+ case REGKEY_VALUE:
+ start = regkey_getidx(0);
+ slots = regkey_getidx(1) - start - 1;
+ break;
+ default:
+ return NULL;
+ }
+
+ bzero(newbuf, sizeof(newbuf));
+
+ for (i = start + slots - 1; i >= start; i--)
+ (void)strcat(newbuf, words[i]);
+
+ return sstrdup(newbuf);
+}
+
void
regkey_add (const char *r)
{
@@ -745,10 +804,10 @@
bzero(reg, sizeof(struct reg));
reg->section = TAILQ_LAST(&sh, section_head);
reg->root = sstrdup(r);
- reg->subkey = sstrdup(words[3]);
- reg->key = sstrdup(words[2]);
- reg->flags = satoi(words[1]);
- reg->value = sstrdup(words[0]);
+ reg->subkey = regkey_get(REGKEY_SUBKEY);
+ reg->key = regkey_get(REGKEY_KEY);
+ reg->flags = satoi(regkey_get(REGKEY_FLAGS));
+ reg->value = regkey_get(REGKEY_VALUE);
TAILQ_INSERT_TAIL(&rh, reg, link);
free(__DECONST(char *, r));
Index: inf.h
===================================================================
RCS file: /data/cvs/src/usr.sbin/ndiscvt/inf.h,v
retrieving revision 1.1
diff -u -r1.1 inf.h
--- inf.h 11 Dec 2003 22:38:14 -0000 1.1
+++ inf.h 27 Nov 2007 12:31:56 -0000
@@ -51,6 +51,11 @@
#define FLG_ADDREG_TYPE_DWORD 0x00010001
#define FLG_ADDREG_TYPE_NONE 0x00020001
+#define REGKEY_SUBKEY 0x0
+#define REGKEY_KEY 0x1
+#define REGKEY_FLAGS 0x2
+#define REGKEY_VALUE 0x3
+
extern void section_add (const char *);
extern void assign_add (const char *);
extern void define_add (const char *);
Patch attached with submission follows:
Index: inf-parse.y
===================================================================
RCS file: /data/cvs/src/usr.sbin/ndiscvt/inf-parse.y,v
retrieving revision 1.2
diff -u -r1.2 inf-parse.y
--- inf-parse.y 2 Jan 2004 04:31:06 -0000 1.2
+++ inf-parse.y 27 Nov 2007 12:31:56 -0000
@@ -95,17 +95,12 @@
;
regkey
- : WORD
+ : WORD regkey
{ push_word($1); }
- | STRING
- { push_word($1); }
- | WORD COMMA regkey
- { push_word($1); }
- | STRING COMMA regkey
+ | STRING regkey
{ push_word($1); }
| COMMA regkey
{ push_word(NULL); }
- | COMMA
- { push_word(NULL); }
+ |
;
%%
Index: inf.c
===================================================================
RCS file: /data/cvs/src/usr.sbin/ndiscvt/inf.c,v
retrieving revision 1.16
diff -u -r1.16 inf.c
--- inf.c 15 May 2005 19:46:14 -0000 1.16
+++ inf.c 27 Nov 2007 12:31:56 -0000
@@ -67,6 +67,8 @@
static void dump_regvals (void);
static void dump_paramreg (const struct section *,
const struct reg *, int);
+static int regkey_getidx(int);
+static char * regkey_get(int);
static FILE *ofp;
@@ -736,6 +738,63 @@
return (0);
}
+static int
+regkey_getidx(int slot)
+{
+ int i, nullcount;
+
+ nullcount = 0;
+
+ if (slot <= 0)
+ return 0;
+
+ for (i = 0; i < idx; i++) {
+ if (words[i] != NULL)
+ continue;
+
+ nullcount++;
+ if (nullcount == slot)
+ break;
+ }
+
+ return i + 1;
+}
+
+static char *
+regkey_get(int rt)
+{
+ int i, start, slots;
+ char newbuf[256];
+
+ switch (rt) {
+ case REGKEY_SUBKEY:
+ start = regkey_getidx(3);
+ slots = regkey_getidx(4) - start - 1;
+ break;
+ case REGKEY_KEY:
+ start = regkey_getidx(2);
+ slots = regkey_getidx(3) - start - 1;
+ break;
+ case REGKEY_FLAGS:
+ start = regkey_getidx(1);
+ slots = regkey_getidx(2) - start - 1;
+ break;
+ case REGKEY_VALUE:
+ start = regkey_getidx(0);
+ slots = regkey_getidx(1) - start - 1;
+ break;
+ default:
+ return NULL;
+ }
+
+ bzero(newbuf, sizeof(newbuf));
+
+ for (i = start + slots - 1; i >= start; i--)
+ (void)strcat(newbuf, words[i]);
+
+ return sstrdup(newbuf);
+}
+
void
regkey_add (const char *r)
{
@@ -745,10 +804,10 @@
bzero(reg, sizeof(struct reg));
reg->section = TAILQ_LAST(&sh, section_head);
reg->root = sstrdup(r);
- reg->subkey = sstrdup(words[3]);
- reg->key = sstrdup(words[2]);
- reg->flags = satoi(words[1]);
- reg->value = sstrdup(words[0]);
+ reg->subkey = regkey_get(REGKEY_SUBKEY);
+ reg->key = regkey_get(REGKEY_KEY);
+ reg->flags = satoi(regkey_get(REGKEY_FLAGS));
+ reg->value = regkey_get(REGKEY_VALUE);
TAILQ_INSERT_TAIL(&rh, reg, link);
free(__DECONST(char *, r));
Index: inf.h
===================================================================
RCS file: /data/cvs/src/usr.sbin/ndiscvt/inf.h,v
retrieving revision 1.1
diff -u -r1.1 inf.h
--- inf.h 11 Dec 2003 22:38:14 -0000 1.1
+++ inf.h 27 Nov 2007 12:31:56 -0000
@@ -51,6 +51,11 @@
#define FLG_ADDREG_TYPE_DWORD 0x00010001
#define FLG_ADDREG_TYPE_NONE 0x00020001
+#define REGKEY_SUBKEY 0x0
+#define REGKEY_KEY 0x1
+#define REGKEY_FLAGS 0x2
+#define REGKEY_VALUE 0x3
+
extern void section_add (const char *);
extern void assign_add (const char *);
extern void define_add (const char *);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list