vgetargskeywords:
+ Generally test nkeywords against 0 instead of keywords against NULL
  (saves a little work if an empty keywords dict is passed, and is
  conceptually more on-target regardless).
+ When a call erroneously specifies a keyword argument both by position
  and by keyword name:
    - It was easy to provoke this routine into an internal buffer overrun
      by using a long argument name.  Now uses PyErr_format instead (which
      computes a safe buffer size).
    - Improved the error msg.
diff --git a/Python/getargs.c b/Python/getargs.c
index dd80fd1..9796b5e 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -1085,16 +1085,16 @@
 	/* make sure there are no duplicate values for an argument;
 	   its not clear when to use the term "keyword argument vs. 
 	   keyword parameter in messages */
-	if (keywords) {
+	if (nkeywords > 0) {
 		for (i = 0; i < nargs; i++) {
 			char *thiskw = kwlist[i];
 			if (thiskw == NULL)
 				break;
 			if (PyMapping_HasKeyString(keywords, thiskw)) {
-				sprintf(msgbuf,
-					"keyword parameter %s redefined",
+				PyErr_Format(PyExc_TypeError,
+					"keyword parameter '%s' was given "
+					"by position and by name",
 					thiskw);
-				PyErr_SetString(PyExc_TypeError, msgbuf);
 				return 0;
 			}
 		}
@@ -1155,29 +1155,23 @@
 	}
 
 	/* handle no keyword parameters in call  */	
-	   	   
-	if (!keywords)
+	if (nkeywords == 0)
 		return 1; 
-		
+
 	/* make sure the number of keywords in the keyword list matches the 
 	   number of items in the format string */
-	  
 	nkwlist = 0;
 	p =  kwlist;
-	for (;;) {
-		if (!*(p++)) break;
+	while (*p++)
 		nkwlist++;
-	}
-
 	if (nkwlist != max) {
 		PyErr_SetString(PyExc_SystemError,
 	  "number of items in format string and keyword list do not match");
 		return 0;
 	}	  	  
-			
+		
 	/* convert the keyword arguments; this uses the format 
 	   string where it was left after processing args */
-	
 	converted = 0;
 	for (i = nargs; i < nkwlist; i++) {
 		PyObject *item;
@@ -1202,9 +1196,8 @@
 			}
 		}
 	}
-	
+
 	/* make sure there are no extraneous keyword arguments */
-	
 	pos = 0;
 	if (converted < nkeywords) {
 		while (PyDict_Next(keywords, &pos, &key, &value)) {