bool ArrayData::hasInternalReference(PointerSet &vars) const { if (supportValueRef()) { for (ArrayIter iter(this); iter; ++iter) { CVarRef var = iter.secondRef(); if (var.isReferenced()) { Variant *pvar = var.getVariantData(); 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 (pobj->o_toArray().get()->hasInternalReference(vars)) { return true; } } else if (var.isArray() && var.getArrayData()->hasInternalReference(vars)) { return true; } } } return false; }
SharedVariant* SharedVariant::convertObj(CVarRef var) { if (!var.is(KindOfObject) || getObjAttempted()) { return NULL; } setObjAttempted(); PointerSet seen; ObjectData *obj = var.getObjectData(); CArrRef arr = obj->o_toArray(); if (arr->hasInternalReference(seen, true)) { return NULL; } SharedVariant *tmp = new SharedVariant(var, false, true, true); tmp->setObjAttempted(); return tmp; }
SharedVariant* SharedVariant::convertObj(CVarRef var) { if (!var.is(KindOfObject) || getObjAttempted()) { return NULL; } setObjAttempted(); PointerSet seen; ObjectData *obj = var.getObjectData(); if (obj->o_instanceof("Serializable")) { // should also check the object itself return NULL; } CArrRef arr = obj->o_toArray(); if (arr->hasInternalReference(seen, true)) { return NULL; } SharedVariant *tmp = new SharedVariant(var, false, true, true); tmp->setObjAttempted(); return tmp; }
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.getVariantData(); 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 (pobj->o_instanceof("Serializable")) { if (ds) { // We want to detect Serializable object as well return true; } else { // Serializable object does not have internal reference issue return false; } } if (pobj->o_toArray().get()->hasInternalReference(vars, ds)) { return true; } } else if (var.isArray() && var.getArrayData()->hasInternalReference(vars, ds)) { return true; } } return false; }