6e7b02933c
The 'r' encoding for unserialization was broken for collections because the code was calling Variant::unserialize() on a temporary Variant, which is a no-no. unserialize() must be called directly on the value where it resides in the collection. Second, there was an inconsistency between serialize and unserialize with how id numbers worked for the 'r' and 'R' encodings. This diff fixes serialize and unserialize to count collection keys when assigning id numbers. I also took the opportunity to tighten up enforcement to prevent collections keys and values from being taken by reference when during unserialization.
73 linhas
2.2 KiB
C++
73 linhas
2.2 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>
|
|
|
|
|
|
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();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
}
|