ignore the coding cookie in compile(), exec(), and eval() if the source is a string #4626
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 9805697..7a27fba 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -494,12 +494,13 @@
 
 
 static char *
-source_as_string(PyObject *cmd, char *funcname, char *what)
+source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf)
 {
 	char *str;
 	Py_ssize_t size;
 
 	if (PyUnicode_Check(cmd)) {
+		cf->cf_flags |= PyCF_IGNORE_COOKIE;
 		cmd = _PyUnicode_AsDefaultEncodedString(cmd, NULL);
 		if (cmd == NULL)
 			return NULL;
@@ -591,7 +592,7 @@
 		return result;
 	}
 
-	str = source_as_string(cmd, "compile", "string, bytes, AST or code");
+	str = source_as_string(cmd, "compile", "string, bytes, AST or code", &cf);
 	if (str == NULL)
 		return NULL;
 
@@ -703,14 +704,14 @@
 		return PyEval_EvalCode((PyCodeObject *) cmd, globals, locals);
 	}
 
-	str = source_as_string(cmd, "eval", "string, bytes or code");
+	cf.cf_flags = PyCF_SOURCE_IS_UTF8;
+	str = source_as_string(cmd, "eval", "string, bytes or code", &cf);
 	if (str == NULL)
 		return NULL;
 
 	while (*str == ' ' || *str == '\t')
 		str++;
 
-	cf.cf_flags = PyCF_SOURCE_IS_UTF8;
 	(void)PyEval_MergeCompilerFlags(&cf);
 	result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
 	Py_XDECREF(tmp);
@@ -779,12 +780,13 @@
 		v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
 	}
 	else {
-		char *str = source_as_string(prog, "exec",
-					     "string, bytes or code");
+		char *str;
 		PyCompilerFlags cf;
+		cf.cf_flags = PyCF_SOURCE_IS_UTF8;
+		str = source_as_string(prog, "exec",
+					     "string, bytes or code", &cf);
 		if (str == NULL)
 			return NULL;
-		cf.cf_flags = PyCF_SOURCE_IS_UTF8;
 		if (PyEval_MergeCompilerFlags(&cf))
 			v = PyRun_StringFlags(str, Py_file_input, globals,
 					      locals, &cf);
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 65c6f5f..dee18b6 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1002,9 +1002,17 @@
 }
 
 /* compute parser flags based on compiler flags */
-#define PARSER_FLAGS(flags) \
-	((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
-		      PyPARSE_DONT_IMPLY_DEDENT : 0)) : 0)
+static int PARSER_FLAGS(PyCompilerFlags *flags)
+{
+	int parser_flags = 0;
+	if (!flags)
+		return 0;
+	if (flags->cf_flags & PyCF_DONT_IMPLY_DEDENT)
+		parser_flags |= PyPARSE_DONT_IMPLY_DEDENT;
+	if (flags->cf_flags & PyCF_IGNORE_COOKIE)
+		parser_flags |= PyPARSE_IGNORE_COOKIE;
+	return parser_flags;
+}
 
 #if 0
 /* Keep an example of flags with future keyword support. */