mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	vgetargskeywords: Verify kwlist has the required length while parsing
the format, instead of waiting until after we can overindex it by mistake.
This commit is contained in:
		
							parent
							
								
									b92cf067c6
								
							
						
					
					
						commit
						62d48e1735
					
				
					 1 changed files with 24 additions and 20 deletions
				
			
		|  | @ -1032,9 +1032,9 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, | |||
| 	char *fname, *message; | ||||
| 	int min, max; | ||||
| 	char *formatsave; | ||||
| 	int i, len, nargs, nkeywords; | ||||
| 	int i, len, nargs, nkeywords, nkwlist; | ||||
| 	char *msg, *ks, **p; | ||||
| 	int nkwlist, pos, match, converted; | ||||
| 	int pos, match, converted; | ||||
| 	PyObject *key, *value; | ||||
| 
 | ||||
| 	assert(args != NULL && PyTuple_Check(args)); | ||||
|  | @ -1048,15 +1048,24 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, | |||
| 	   name <- routine name, if any (else NULL). | ||||
| 	   min <- # of required arguments, or -1 if all are required. | ||||
| 	   max <- most arguments (required + optional). | ||||
| 	   Check that kwlist has a non-NULL entry for each arg. | ||||
| 	   Raise error if a tuple arg spec is found. | ||||
| 	*/ | ||||
| 	fname = message = NULL; | ||||
| 	formatsave = format; | ||||
| 	p = kwlist; | ||||
| 	min = -1; | ||||
| 	max = 0; | ||||
| 	while ((i = *format++) != '\0') { | ||||
| 		if (isalpha(i) && i != 'e') | ||||
| 		if (isalpha(i) && i != 'e') { | ||||
| 			max++; | ||||
| 			if (*p == NULL) { | ||||
| 				/* kwlist is too short */ | ||||
| 				PyErr_BadInternalCall(); | ||||
| 				return 0; | ||||
| 			} | ||||
| 			p++; | ||||
| 		} | ||||
| 		else if (i == '|') | ||||
| 			min = max; | ||||
| 		else if (i == ':') { | ||||
|  | @ -1072,13 +1081,19 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, | |||
| 		      "tuple found in format when using keyword arguments"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	}	 | ||||
| 	} | ||||
| 	format = formatsave; | ||||
| 	if (*p != NULL) { | ||||
| 		/* kwlist is too long */ | ||||
| 		PyErr_BadInternalCall(); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (min < 0) { | ||||
| 		/* All arguments are required. */ | ||||
| 		min = max; | ||||
| 	} | ||||
| 	format = formatsave; | ||||
| 
 | ||||
| 	nkwlist = max; | ||||
| 	nargs = PyTuple_GET_SIZE(args); | ||||
| 	nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); | ||||
| 
 | ||||
|  | @ -1103,9 +1118,11 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, | |||
| 	} | ||||
| 
 | ||||
| 	/* required arguments missing from args can be supplied by keyword 
 | ||||
| 	   arguments */ | ||||
| 	   arguments; set len to the number of posiitional arguments, and, | ||||
| 	   if that's less than the minimum required, add in the number of | ||||
| 	   required arguments that are supplied by keywords */ | ||||
| 	len = nargs; | ||||
| 	if (keywords && nargs < min) { | ||||
| 	if (nkeywords > 0 && nargs < min) { | ||||
| 		for (i = nargs; i < min; i++) { | ||||
| 			if (PyDict_GetItemString(keywords, kwlist[i])) | ||||
| 				len++; | ||||
|  | @ -1118,7 +1135,6 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, | |||
| 	   is a little confusing with keywords since keyword arguments | ||||
| 	   which are supplied, but don't match the required arguments | ||||
| 	   are not included in the "%d given" part of the message */ | ||||
| 
 | ||||
| 	if (len < min || max < len) { | ||||
| 		if (message == NULL) { | ||||
| 			sprintf(msgbuf, | ||||
|  | @ -1151,18 +1167,6 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, | |||
| 	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; | ||||
| 	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; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Tim Peters
						Tim Peters