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
This commit is contained in:
parent
4e88baead9
commit
eadca3e467
|
@ -968,15 +968,18 @@ class JsComparator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JsComparator(const char* funcName, ScriptRun* runner)
|
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;
|
const char* m_name;
|
||||||
ScriptRun* m_runner;
|
ScriptRun* m_runner;
|
||||||
|
bool m_failed;
|
||||||
};
|
};
|
||||||
|
|
||||||
int compare(GenObject* op1, GenObject* op2, void* data)
|
int compare(GenObject* op1, GenObject* op2, void* data)
|
||||||
{
|
{
|
||||||
JsComparator* cmp = static_cast<JsComparator*>(data);
|
JsComparator* cmp = static_cast<JsComparator*>(data);
|
||||||
|
if (cmp && cmp->m_failed)
|
||||||
|
return 0;
|
||||||
if (!(cmp && cmp->m_runner))
|
if (!(cmp && cmp->m_runner))
|
||||||
return ::strcmp(*(static_cast<String*>(op1)),*(static_cast<String*>(op2)));
|
return ::strcmp(*(static_cast<String*>(op1)),*(static_cast<String*>(op2)));
|
||||||
ScriptRun* runner = cmp->m_runner->code()->createRunner(cmp->m_runner->context());
|
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);
|
ScriptRun::Status rval = runner->call(cmp->m_name,stack);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (ScriptRun::Succeeded == rval) {
|
if (ScriptRun::Succeeded == rval) {
|
||||||
String* sret = static_cast<String*>(ExpEvaluator::popOne(runner->stack()));
|
ExpOperation* sret = static_cast<ExpOperation*>(ExpEvaluator::popOne(runner->stack()));
|
||||||
ret = sret->toInteger();
|
if (sret) {
|
||||||
TelEngine::destruct(sret);
|
ret = sret->toInteger();
|
||||||
|
TelEngine::destruct(sret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cmp->m_failed = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
cmp->m_failed = true;
|
||||||
TelEngine::destruct(runner);
|
TelEngine::destruct(runner);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1014,17 +1023,20 @@ bool JsArray::runNativeSort(ObjList& stack, const ExpOperation& oper, GenObject*
|
||||||
return false;
|
return false;
|
||||||
JsComparator* comp = op ? new JsComparator(op->name() ,runner) : 0;
|
JsComparator* comp = op ? new JsComparator(op->name() ,runner) : 0;
|
||||||
sorted.sort(&compare,comp);
|
sorted.sort(&compare,comp);
|
||||||
|
bool ok = comp ? !comp->m_failed : true;
|
||||||
delete comp;
|
delete comp;
|
||||||
int i = 0;
|
if (ok) {
|
||||||
for (ObjList* o = sorted.skipNull();o;o = o->skipNext()) {
|
int i = 0;
|
||||||
NamedString* slice = static_cast<NamedString*>(o->get());
|
for (ObjList* o = sorted.skipNull();o;o = o->skipNext()) {
|
||||||
String* name = (String*)(&slice->name());
|
NamedString* slice = static_cast<NamedString*>(o->get());
|
||||||
*name = String(i++);
|
String* name = (String*)(&slice->name());
|
||||||
params().addParam(slice);
|
*name = String(i++);
|
||||||
o->setDelete(false);
|
params().addParam(slice);
|
||||||
|
o->setDelete(false);
|
||||||
|
}
|
||||||
|
setLength(i);
|
||||||
}
|
}
|
||||||
setLength(i);
|
return ok;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue