Created
March 14, 2014 01:50
-
-
Save msteveb/9540791 to your computer and use it in GitHub Desktop.
im.c: check for missing quotes, etc. in eval
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 8b6291877ea24eaa9aa29928e8ed468f5015aa48 Mon Sep 17 00:00:00 2001 | |
From: Steve Bennett <steveb@workware.net.au> | |
Date: Fri, 14 Mar 2014 11:46:22 +1000 | |
Subject: [PATCH 2/2] jim.c: check for missing quotes, etc. in eval | |
Throw an error if a script is missing a trailing bracket, brace or quote rather than | |
simply ignoring the error. | |
Reported-by: florian.schaefer+github@gmail.com | |
Signed-off-by: Steve Bennett <steveb@workware.net.au> | |
--- | |
jim.c | 69 ++++++++++++++++++++++++++++++++++++-------------------- | |
tests/parse.test | 4 ++-- | |
2 files changed, 46 insertions(+), 27 deletions(-) | |
diff --git a/jim.c b/jim.c | |
index e09db07..3abc199 100644 | |
--- a/jim.c | |
+++ b/jim.c | |
@@ -1193,7 +1193,6 @@ static int JimParseStr(struct JimParserCtx *pc); | |
static int JimParseComment(struct JimParserCtx *pc); | |
static void JimParseSubCmd(struct JimParserCtx *pc); | |
static int JimParseSubQuote(struct JimParserCtx *pc); | |
-static void JimParseSubCmd(struct JimParserCtx *pc); | |
static Jim_Obj *JimParserGetTokenObj(Jim_Interp *interp, struct JimParserCtx *pc); | |
/* Initialize a parser context. | |
@@ -3646,6 +3645,12 @@ static int SetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, struct J | |
return JIM_OK; | |
} | |
+/** | |
+ * Returns NULL if the script failed to parse and leaves | |
+ * an error message in the interp result. | |
+ * | |
+ * Otherwise returns a parsed script object. | |
+ */ | |
ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr) | |
{ | |
if (objPtr == interp->emptyObj) { | |
@@ -3654,7 +3659,36 @@ ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr) | |
} | |
if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { | |
- SetScriptFromAny(interp, objPtr, NULL); | |
+ struct JimParseResult result; | |
+ int ret = SetScriptFromAny(interp, objPtr, &result); | |
+ if (ret == JIM_ERR) { | |
+ const char *msg; | |
+ char linebuf[20]; | |
+ | |
+ switch (result.missing) { | |
+ case '[': | |
+ msg = "unmatched \"[\""; | |
+ break; | |
+ case '{': | |
+ msg = "missing close-brace"; | |
+ break; | |
+ case '"': | |
+ default: | |
+ msg = "missing quote"; | |
+ break; | |
+ } | |
+ | |
+ snprintf(linebuf, sizeof(linebuf), "%d", result.line); | |
+ | |
+ if (objPtr->typePtr == &sourceObjType) { | |
+ Jim_SetResultFormatted(interp, "%s in \"%#s\" at line %s", | |
+ msg, objPtr->internalRep.sourceValue.fileNameObj, linebuf); | |
+ } | |
+ else { | |
+ Jim_SetResultString(interp, msg, -1); | |
+ } | |
+ return NULL; | |
+ } | |
} | |
return (ScriptObj *) Jim_GetIntRepPtr(objPtr); | |
} | |
@@ -10406,6 +10440,10 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) | |
Jim_IncrRefCount(scriptObjPtr); /* Make sure it's shared. */ | |
script = Jim_GetScript(interp, scriptObjPtr); | |
+ if (script == NULL) { | |
+ Jim_DecrRefCount(interp, scriptObjPtr); | |
+ return JIM_ERR; | |
+ } | |
/* Reset the interpreter result. This is useful to | |
* return the empty result in the case of empty program. */ | |
@@ -10942,7 +10980,6 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename) | |
struct stat sb; | |
int retcode; | |
int readlen; | |
- struct JimParseResult result; | |
if (stat(filename, &sb) != 0 || (fp = fopen(filename, "rt")) == NULL) { | |
Jim_SetResultFormatted(interp, "couldn't read file \"%s\": %s", filename, strerror(errno)); | |
@@ -10969,27 +11006,7 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename) | |
Jim_IncrRefCount(scriptObjPtr); | |
/* Now check the script for unmatched braces, etc. */ | |
- if (SetScriptFromAny(interp, scriptObjPtr, &result) == JIM_ERR) { | |
- const char *msg; | |
- char linebuf[20]; | |
- | |
- switch (result.missing) { | |
- case '[': | |
- msg = "unmatched \"[\""; | |
- break; | |
- case '{': | |
- msg = "missing close-brace"; | |
- break; | |
- case '"': | |
- default: | |
- msg = "missing quote"; | |
- break; | |
- } | |
- | |
- snprintf(linebuf, sizeof(linebuf), "%d", result.line); | |
- | |
- Jim_SetResultFormatted(interp, "%s in \"%s\" at line %s", | |
- msg, filename, linebuf); | |
+ if (Jim_GetScript(interp, scriptObjPtr) == NULL) { | |
Jim_DecrRefCount(interp, scriptObjPtr); | |
return JIM_ERR; | |
} | |
@@ -11604,7 +11621,7 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv | |
incrScript = Jim_GetScript(interp, argv[3]); | |
/* Ensure proper lengths to start */ | |
- if (incrScript->len != 3 || !expr || expr->len != 3) { | |
+ if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) { | |
goto evalstart; | |
} | |
/* Ensure proper token types. */ | |
@@ -12765,6 +12782,8 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar | |
return JIM_ERR; | |
} | |
script = Jim_GetScript(interp, argv[2]); | |
+ if (script == NULL) | |
+ return JIM_ERR; | |
Jim_SetResultInt(interp, script->len); | |
return JIM_OK; | |
} | |
diff --git a/tests/parse.test b/tests/parse.test | |
index 982c4a4..2ee2127 100644 | |
--- a/tests/parse.test | |
+++ b/tests/parse.test | |
@@ -153,9 +153,9 @@ test parse-1.28 "nested dict sugar" { | |
set dq {"} | |
set script "set x ${dq}hello" | |
-test parse-1.29 "missing quote" jim { | |
+test parse-1.29 "missing quote" -constraints jim -body { | |
eval $script | |
-} hello | |
+} -returnCodes error -match glob -result {missing quote in "*" at line 154} | |
test parse-1.30 "missing quote" { | |
info complete $script | |
-- | |
1.8.3.4 (Apple Git-47) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment