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