Arquivos
hhvm/hphp/runtime/base/variable_unserializer.cpp
T
bertrand 6a93844442 Add support for safe (un)serialization using (un)serialize()
The unserialization of random objects may be dangerous because the destructor of the object will be called when the unserialized objects are out of scope. However, the person who wrote the class may not be aware of the danger of unserialization. Therefore, we would like to require every users of the unserialize() to provide a whitelist of the class names that are authorized to be unserialized so that we can make sure the object is safe to be unserialized.

Add a parameter 'class_whitelist' to unserialize() function to determine whether to raise warnings for unsafe unserialization. If the class to be unserialized is not an instance of Serilizable or not in the whitelist, warnings will be raised. For the detailed reason why we need this, please see http://fburl.com/SafeSerializable for more information.

Add a parameter 'all_classes_enabled' to allow  those hphp functions that need to unserialize any class. For example, fb_call_user_func_async() will need to serialize and nserialize the given parameters.
2013-04-18 13:54:55 -07:00

89 linhas
2.8 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include <runtime/base/variable_unserializer.h>
#include <runtime/base/complex_types.h>
#include <runtime/base/zend/zend_strtod.h>
#include <runtime/base/array/array_iterator.h>
#include <runtime/ext/ext_class.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
Variant VariableUnserializer::unserialize() {
Variant v;
v.unserialize(this);
return v;
}
Variant VariableUnserializer::unserializeKey() {
Variant v;
v.unserialize(this, Uns::KeyMode);
return v;
}
int64_t VariableUnserializer::readInt() {
check();
char *newBuf;
int64_t r = strtoll(m_buf, &newBuf, 10);
m_buf = newBuf;
return r;
}
double VariableUnserializer::readDouble() {
check();
char *newBuf;
double r = zend_strtod(m_buf, &newBuf);
m_buf = newBuf;
return r;
}
void VariableUnserializer::read(char *buf, uint n) {
check();
/* compute copy boundaries in a more efficient manner,
by using min(...) operation rather than complex conditional
in a loop guard */
const size_t BUFFER_SIZE = m_end - m_buf;
const size_t BUFFER_LIMIT = std::min(BUFFER_SIZE, size_t(n));
memcpy(buf, m_buf, BUFFER_LIMIT);
m_buf += BUFFER_LIMIT;
}
Variant &VariableUnserializer::addVar() {
m_vars.push_back(uninit_null());
return m_vars.back();
}
bool VariableUnserializer::isWhitelistedClass(CStrRef cls_name) const {
if (m_type != Serialize || m_classWhiteList.isNull()) {
return true;
}
if (!m_classWhiteList.isNull() && !m_classWhiteList.empty()) {
for (ArrayIter iter(m_classWhiteList); iter; ++iter) {
CVarRef value(iter.secondRef());
if (f_is_subclass_of(cls_name, value) || value.same(cls_name)) {
return true;
}
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
}