コード例 #1
0
ファイル: string_data.cpp プロジェクト: Braunson/hiphop-php
StringData::StringData(const char *data, int len, StringDataMode mode)
  : m_data(NULL), _count(0), m_len(0) {
  m_hash = 0;
  assign(data, len, mode);

  TAINT_OBSERVER_REGISTER_MUTATED(this);
}
コード例 #2
0
ファイル: string_buffer.cpp プロジェクト: AviMoto/hiphop-php
void StringBuffer::absorb(StringBuffer &buf) {
  if (empty()) {
    TAINT_OBSERVER_REGISTER_ACCESSED(buf.getTaintDataRefConst());
    TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());

    StringData* str = m_str;

    m_str = buf.m_str;
    m_buffer = buf.m_buffer;
    m_len = buf.m_len;
    m_cap = buf.m_cap;

    buf.m_str = str;
    if (str) {
      buf.m_buffer = (char*)str->data();
      buf.m_len = str->size();
      buf.m_cap = str->capacity();
    } else {
      buf.m_buffer = 0;
      buf.m_len = 0;
      buf.m_cap = 0;
    }
    buf.reset();
  } else {
    // REGISTER_ACCESSED()/REGISTER_MUTATED() are called by append()/detach()
    append(buf.detach());
  }
}
コード例 #3
0
ファイル: string_buffer.cpp プロジェクト: AviMoto/hiphop-php
CstrBuffer::CstrBuffer(const char *filename)
  : m_buffer(NULL), m_len(0) {
  struct stat sb;
  if (stat(filename, &sb) == 0) {
    if (sb.st_size > kMaxCap - 1) {
      std::ostringstream out;
      out << "file " << filename << " is too large";
      throw StringBufferLimitException(kMaxCap,
                                       String(out.str().c_str()));
    }
    m_cap = sb.st_size;
    m_buffer = (char *)Util::safe_malloc(m_cap + 1);

    int fd = ::open(filename, O_RDONLY);
    if (fd != -1) {
      while (m_len < m_cap) {
        int buffer_size = m_cap - m_len;
        int len = ::read(fd, m_buffer + m_len, buffer_size);
        if (len == -1 && errno == EINTR) continue;
        if (len <= 0) break;
        m_len += len;
      }
      ::close(fd);
    }
  }
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
コード例 #4
0
ファイル: string_buffer.cpp プロジェクト: AviMoto/hiphop-php
StringBuffer::StringBuffer(int initialSize /* = 63 */)
  : m_initialCap(initialSize), m_maxBytes(kDefaultOutputLimit),
    m_cap(initialSize), m_len(0) {
  ASSERT(initialSize > 0);
  m_str = NEW(StringData)(initialSize);
  m_buffer = (char *)m_str->data();
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
コード例 #5
0
ファイル: string_data.cpp プロジェクト: Braunson/hiphop-php
StringData::StringData(const char *data,
                       StringDataMode mode /* = AttachLiteral */)
  : m_data(NULL), _count(0), m_len(0) {
  m_hash = 0;

  assign(data, mode);

  TAINT_OBSERVER_REGISTER_MUTATED(this);
}
コード例 #6
0
StringBuffer::StringBuffer(int initialSize /* = 63 */)
  : m_initialCap(initialSize), m_maxBytes(kDefaultOutputLimit),
    m_len(0) {
  assert(initialSize > 0);
  m_str = NEW(StringData)(initialSize);
  MutableSlice s = m_str->mutableSlice();
  m_buffer = s.ptr;
  m_cap = s.len;
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
コード例 #7
0
HOT_FUNC
StringData::StringData(SharedVariant *shared)
  : _count(0) {
  ASSERT(shared);
  shared->incRef();
  m_hash = 0;
  m_len = shared->stringLength();
  m_cdata = shared->stringData();
  m_big.shared = shared;
  m_big.cap = m_len | IsShared;
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, rawdata());
}
コード例 #8
0
ファイル: string_data.cpp プロジェクト: Braunson/hiphop-php
StringData::StringData(SharedVariant *shared)
  : m_data(NULL), _count(0), m_len(0) {
  m_hash = 0;

  ASSERT(shared);
  shared->incRef();
  m_shared = shared;
  m_data = m_shared->stringData();
  m_len = m_shared->stringLength() | IsShared;
  ASSERT(m_data);

  TAINT_OBSERVER_REGISTER_MUTATED(this);
}
コード例 #9
0
void StringData::initLiteral(const char* data, int len) {
  if (uint32_t(len) > MaxSize) {
    throw InvalidArgumentException("len>=2^30", len);
  }
  // Do not copy literals, this StringData can have a shorter lifetime than
  // the literal, and the client can count on this->data() giving back
  // the literal ptr with the longer lifetime. Sketchy!
  m_hash = 0;
  _count = 0;
  m_len = len;
  m_cdata = data;
  m_big.cap = len | IsLiteral;
  ASSERT(checkSane());
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, rawdata());
}
コード例 #10
0
void StringData::initAttachDeprecated(const char* data, int len) {
  if (uint32_t(len) > MaxSize) {
    throw InvalidArgumentException("len>=2^30", len);
  }
  // Don't copy small strings here either because the caller sometimes
  // assumes he can mess with data while this string is still alive,
  // and we want to free it eagerly. Sketchy!
  m_hash = 0;
  _count = 0;
  m_len = len;
  m_cdata = data;
  m_big.cap = len | IsMalloc;
  ASSERT(checkSane());
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, rawdata());
}
コード例 #11
0
ファイル: string_data.cpp プロジェクト: Braunson/hiphop-php
void StringData::append(const char *s, int len) {
  if (len == 0) return;

  if (len < 0 || (len & IsMask)) {
    throw InvalidArgumentException("len: %d", len);
  }

  ASSERT(!isStatic()); // never mess around with static strings!

  if (!isMalloced()) {
    int newlen;
    m_data = string_concat(data(), size(), s, len, newlen);
    if (isShared()) {
      m_shared->decRef();
    }
    m_len = newlen;
    m_hash = 0;
  } else if (m_data == s) {
    int newlen;
    char *newdata = string_concat(data(), size(), s, len, newlen);
    releaseData();
    m_data = newdata;
    m_len = newlen;
  } else {
    int dataLen = size();
    ASSERT((m_data > s && m_data - s > len) ||
           (m_data < s && s - m_data > dataLen)); // no overlapping
    m_len = len + dataLen;
    m_data = (const char*)realloc((void*)m_data, m_len + 1);
    memcpy((void*)(m_data + dataLen), s, len);
    ((char*)m_data)[m_len] = '\0';
    m_hash = 0;
  }

  if (m_len & IsMask) {
    int len = m_len;
    m_len &= ~IsMask;
    releaseData();
    m_data = NULL;
    throw FatalErrorException(0, "String length exceeded 2^29 - 1: %d", len);
  }

  TAINT_OBSERVER_REGISTER_MUTATED(this);
}
コード例 #12
0
void StringBuffer::absorb(StringBuffer &buf) {
  if (empty()) {
    TAINT_OBSERVER_REGISTER_ACCESSED(buf.getTaintDataRefConst());
    TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data);

    char *buffer = m_buffer;
    int size = m_size;

    m_buffer = buf.m_buffer;
    m_size = buf.m_size;
    m_pos = buf.m_pos;

    buf.m_buffer = buffer;
    buf.m_size = size;
    buf.reset();
  } else {
    append(buf.detach());
  }
}
コード例 #13
0
StringBuffer::StringBuffer(const char *filename)
  : m_buffer(NULL), m_initialSize(1024), m_maxBytes(0), m_size(0), m_pos(0) {
  struct stat sb;
  if (stat(filename, &sb) == 0) {
    m_size = sb.st_size;
    m_buffer = (char *)Util::safe_malloc(m_size + 1);

    int fd = ::open(filename, O_RDONLY);
    if (fd != -1) {
      while (m_pos < m_size) {
        int buffer_size = m_size - m_pos;
        int len = ::read(fd, m_buffer + m_pos, buffer_size);
        if (len == -1 && errno == EINTR) continue;
        if (len <= 0) break;
        m_pos += len;
      }
      ::close(fd);
    }
  }
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
コード例 #14
0
HOT_FUNC
void StringData::initAttach(const char* data, int len) {
  if (uint32_t(len) > MaxSize) {
    throw InvalidArgumentException("len>=2^30", len);
  }
  m_hash = 0;
  _count = 0;
  if (uint32_t(len) <= MaxSmallSize) {
    memcpy(m_small, data, len);
    m_len = len;
    m_data = m_small;
    m_small[len] = 0;
    m_small[MaxSmallSize] = 0;
    free((void*)data);
  } else {
    m_len = len;
    m_cdata = data;
    m_big.cap = len | IsMalloc;
  }
  ASSERT(checkSane());
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, rawdata());
}
コード例 #15
0
ファイル: string_buffer.cpp プロジェクト: AviMoto/hiphop-php
CstrBuffer::CstrBuffer(int cap)
  : m_buffer((char*)Util::safe_malloc(cap + 1)), m_len(0), m_cap(cap) {
  ASSERT(unsigned(cap) <= kMaxCap);
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
コード例 #16
0
StringBuffer::StringBuffer(int initialSize /* = 1024 */)
  : m_initialSize(initialSize), m_maxBytes(0), m_size(initialSize), m_pos(0) {
  ASSERT(initialSize > 0);
  m_buffer = (char *)Util::safe_malloc(initialSize + 1);
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
コード例 #17
0
StringBuffer::StringBuffer(char *data, int len)
  : m_buffer(data), m_initialSize(1024), m_maxBytes(0), m_size(len),
    m_pos(len) {
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, dataIgnoreTaint());
}
コード例 #18
0
void StringData::append(const char *s, int len) {
  ASSERT(!isStatic()); // never mess around with static strings!
  if (len == 0) return;
  if (UNLIKELY(uint32_t(len) > MaxSize)) {
    throw InvalidArgumentException("len>=2^30", len);
  }
  if (UNLIKELY(len + m_len > MaxSize)) {
    throw FatalErrorException(0, "String length exceeded 2^30 - 1: %u",
                              len + m_len);
  }
  int newlen;
  // TODO: t1122987: in any of the cases below where we need a bigger buffer,
  // we can probably assume we're in a concat-loop and pick a good buffer
  // size to avoid O(N^2) copying cost.
  if (isShared() || isLiteral()) {
    // buffer is immutable, don't modify it.
    // We are mutating, so we don't need to repropagate our own taint
    StringSlice r = slice();
    char* newdata = string_concat(r.ptr, r.len, s, len, newlen);
    if (isShared()) m_big.shared->decRef();
    m_len = newlen;
    m_data = newdata;
    m_big.cap = newlen | IsMalloc;
    m_hash = 0;
  } else if (rawdata() == s) {
    // appending ourself to ourself, be conservative.
    // We are mutating, so we don't need to repropagate our own taint
    StringSlice r = slice();
    char *newdata = string_concat(r.ptr, r.len, s, len, newlen);
    releaseData();
    m_len = newlen;
    m_data = newdata;
    m_big.cap = newlen | IsMalloc;
    m_hash = 0;
  } else if (isSmall()) {
    // we're currently small but might not be after append.
    // We are mutating, so we don't need to repropagate our own taint
    int oldlen = m_len;
    newlen = oldlen + len;
    if (unsigned(newlen) <= MaxSmallSize) {
      // win.
      memcpy(&m_small[oldlen], s, len);
      m_small[newlen] = 0;
      m_small[MaxSmallSize] = 0;
      m_len = newlen;
      m_data = m_small;
      m_hash = 0;
    } else {
      // small->big string transition.
      char *newdata = string_concat(m_small, oldlen, s, len, newlen);
      m_len = newlen;
      m_data = newdata;
      m_big.cap = newlen | IsMalloc;
      m_hash = 0;
    }
  } else {
    // generic "big string concat" path.  realloc buffer.
    int oldlen = m_len;
    char* oldp = m_data;
    ASSERT((oldp > s && oldp - s > len) ||
           (oldp < s && s - oldp > oldlen)); // no overlapping
    newlen = oldlen + len;
    char* newdata = (char*) realloc(oldp, newlen + 1);
    memcpy(newdata + oldlen, s, len);
    newdata[newlen] = 0;
    m_len = newlen;
    m_data = newdata;
    m_big.cap = newlen | IsMalloc;
    m_hash = 0;
  }
  ASSERT(uint32_t(newlen) <= MaxSize);
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data, rawdata());
  ASSERT(checkSane());
}
コード例 #19
0
void StringBuffer::append(CStrRef s) {
  append(s.data(), s.size());
  TAINT_OBSERVER_REGISTER_MUTATED(m_taint_data);
}