bool ArrayData::hasInternalReference(PointerSet &vars, bool ds /* = false */) const { if (isSharedMap()) return false; for (ArrayIter iter(this); iter; ++iter) { CVarRef var = iter.secondRef(); if (var.isReferenced()) { Variant *pvar = var.getRefData(); if (vars.find(pvar) != vars.end()) { return true; } vars.insert(pvar); } if (var.isObject()) { ObjectData *pobj = var.getObjectData(); if (vars.find(pobj) != vars.end()) { return true; } vars.insert(pobj); if (ds && pobj->o_instanceof("Serializable")) { return true; } if (pobj->hasInternalReference(vars, ds)) { return true; } } else if (var.isArray() && var.getArrayData()->hasInternalReference(vars, ds)) { return true; } } return false; }
SharedVariant* SharedVariant::convertObj(CVarRef var) { if (!var.is(KindOfObject) || getObjAttempted()) { return nullptr; } setObjAttempted(); ObjectData *obj = var.getObjectData(); if (obj->instanceof(SystemLib::s_SerializableClass)) { // should also check the object itself return nullptr; } PointerSet seen; if (obj->hasInternalReference(seen, true)) { return nullptr; } SharedVariant *tmp = new SharedVariant(var, false, true, true); tmp->setObjAttempted(); return tmp; }
APCHandle* APCObject::MakeAPCObject(APCHandle* obj, CVarRef value) { if (!value.is(KindOfObject) || obj->getObjAttempted()) { return nullptr; } obj->setObjAttempted(); ObjectData *o = value.getObjectData(); if (o->instanceof(SystemLib::s_SerializableClass)) { // should also check the object itself return nullptr; } PointerSet seen; if (o->hasInternalReference(seen, true)) { return nullptr; } APCHandle* tmp = APCHandle::Create(value, false, true, true); tmp->setObjAttempted(); return tmp; }