Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save msteveb/9540791 to your computer and use it in GitHub Desktop.
Save msteveb/9540791 to your computer and use it in GitHub Desktop.
im.c: check for missing quotes, etc. in eval
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