From eadca3e467e53ba17a34abbdcf1d17b96a6f23e0 Mon Sep 17 00:00:00 2001 From: oana Date: Fri, 16 May 2014 10:40:56 +0000 Subject: [PATCH] Bug fix: check that we extract a valid pointer from the stack when running the compare function for Array.sort(). This avoids segmentation faults caused by a callback compare function for Array.sort() which doesn't return anything. Instead, signal a runtime error. git-svn-id: http://yate.null.ro/svn/yate/trunk@5833 acf43c95-373e-0410-b603-e72c3f656dc1 --- libs/yscript/jsobjects.cpp | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/libs/yscript/jsobjects.cpp b/libs/yscript/jsobjects.cpp index d3353783..e7a9ac56 100644 --- a/libs/yscript/jsobjects.cpp +++ b/libs/yscript/jsobjects.cpp @@ -968,15 +968,18 @@ class JsComparator { public: JsComparator(const char* funcName, ScriptRun* runner) - : m_name(funcName), m_runner(runner) + : m_name(funcName), m_runner(runner), m_failed(false) { } const char* m_name; ScriptRun* m_runner; + bool m_failed; }; int compare(GenObject* op1, GenObject* op2, void* data) { JsComparator* cmp = static_cast(data); + if (cmp && cmp->m_failed) + return 0; if (!(cmp && cmp->m_runner)) return ::strcmp(*(static_cast(op1)),*(static_cast(op2))); ScriptRun* runner = cmp->m_runner->code()->createRunner(cmp->m_runner->context()); @@ -988,10 +991,16 @@ int compare(GenObject* op1, GenObject* op2, void* data) ScriptRun::Status rval = runner->call(cmp->m_name,stack); int ret = 0; if (ScriptRun::Succeeded == rval) { - String* sret = static_cast(ExpEvaluator::popOne(runner->stack())); - ret = sret->toInteger(); - TelEngine::destruct(sret); + ExpOperation* sret = static_cast(ExpEvaluator::popOne(runner->stack())); + if (sret) { + ret = sret->toInteger(); + TelEngine::destruct(sret); + } + else + cmp->m_failed = true; } + else + cmp->m_failed = true; TelEngine::destruct(runner); return ret; } @@ -1014,17 +1023,20 @@ bool JsArray::runNativeSort(ObjList& stack, const ExpOperation& oper, GenObject* return false; JsComparator* comp = op ? new JsComparator(op->name() ,runner) : 0; sorted.sort(&compare,comp); + bool ok = comp ? !comp->m_failed : true; delete comp; - int i = 0; - for (ObjList* o = sorted.skipNull();o;o = o->skipNext()) { - NamedString* slice = static_cast(o->get()); - String* name = (String*)(&slice->name()); - *name = String(i++); - params().addParam(slice); - o->setDelete(false); + if (ok) { + int i = 0; + for (ObjList* o = sorted.skipNull();o;o = o->skipNext()) { + NamedString* slice = static_cast(o->get()); + String* name = (String*)(&slice->name()); + *name = String(i++); + params().addParam(slice); + o->setDelete(false); + } + setLength(i); } - setLength(i); - return true; + return ok; }