Example #1
0
String xml_utf8_decode(const XML_Char *s, int len,
                       const XML_Char *encoding) {
  String str = String(len, ReserveString);
  char *newbuf = str.mutableData();
  char (*decoder)(unsigned short) = nullptr;
  xml_encoding *enc = xml_get_encoding(encoding);

  int newlen = 0;
  if (enc) {
    decoder = enc->decoding_function;
  }
  if (decoder == nullptr) {
    /* If the target encoding was unknown, or no decoder function
     * was specified, return the UTF-8-encoded data as-is.
     */
    memcpy(newbuf, s, len);
    str.setSize(len);
    return str;
  }

  UTF8To16Decoder dec(s, len, true);
  for (int b = dec.decode(); b != UTF8_END; b = dec.decode()) {
    newbuf[newlen] = decoder(b);
    ++newlen;
  }

  assert(newlen <= len);
  str.shrink(newlen);
  return str;
}
Example #2
0
String f_posix_ctermid() {
  String s = String(L_ctermid, ReserveString);
  char *buffer = s.bufferSlice().ptr;
  ctermid(buffer);
  s.setSize(strlen(buffer));
  return s;
}
Example #3
0
String f_posix_getcwd() {
  String s = String(PATH_MAX, ReserveString);
  char *buffer = s.bufferSlice().ptr;
  if (getcwd(buffer, PATH_MAX) == NULL) {
    return "/";
  }
  s.setSize(strlen(buffer));
  return s;
}
Example #4
0
Variant HHVM_FUNCTION(snappy_uncompress, const String& data) {
  size_t dsize;
  if (!snappy::GetUncompressedLength(data.data(), data.size(), &dsize)) {
    return false;
  }

  String s = String(dsize, ReserveString);
  if (!snappy::RawUncompress(data.data(), data.size(), s.mutableData())) {
    return false;
  }
  return s.setSize(dsize);
}
bool FileRepository::readActualFile(const StringData *name,
                                    const struct stat &s,
                                    FileInfo &fileInfo) {
  if (s.st_size > StringData::MaxSize) {
    throw FatalErrorException(0, "file %s is too big", name->data());
  }
  int fileSize = s.st_size;
  int fd = open(name->data(), O_RDONLY);
  if (!fd) return false; // ignore file open exception
  String str = String(fileSize, ReserveString);
  char *input = str.bufferSlice().ptr;
  if (!input) return false;
  int nbytes = read(fd, input, fileSize);
  close(fd);
  str.setSize(fileSize);
  fileInfo.m_inputString = str;
  if (nbytes != fileSize) return false;

  computeMd5(name, fileInfo);
  return true;
}
Example #6
0
Variant f_stream_get_contents(CResRef handle, int maxlen /* = -1 */,
                              int offset /* = -1 */) {
  if (maxlen < -1) {
    throw_invalid_argument("maxlen: %d", maxlen);
    return false;
  }

  if (maxlen == 0) {
    return String();
  }

  File *file = handle.getTyped<File>(false /* nullOkay */,
                                     true /* badTypeOkay */);
  if (!file) {
    throw_invalid_argument(
      "stream_get_contents() expects parameter 1 to be a resource");
    return false;
  }

  if (offset >= 0 && !file->seek(offset, SEEK_SET) ) {
    raise_warning("Failed to seek to position %d in the stream", offset);
    return false;
  }

  String ret;
  if (maxlen != -1) {
    ret = String(maxlen, ReserveString);
    char *buf = ret.bufferSlice().ptr;
    maxlen = file->readImpl(buf, maxlen);
    if (maxlen < 0) {
      return false;
    }
    ret.setSize(maxlen);
  } else {
    StringBuffer sb;
    sb.read(file);
    ret = sb.detach();
  }
  return ret;
}
Example #7
0
static Variant mcrypt_generic(const Resource& td, const String& data,
                              bool dencrypt) {
  MCrypt *pm = td.getTyped<MCrypt>();
  if (!pm->m_init) {
    raise_warning("Operation disallowed prior to mcrypt_generic_init().");
    return false;
  }

  if (data.empty()) {
    raise_warning("An empty string was passed");
    return false;
  }

  String s;
  unsigned char* data_s;
  int block_size, data_size;
  /* Check blocksize */
  if (mcrypt_enc_is_block_mode(pm->m_td) == 1) { /* It's a block algorithm */
    block_size = mcrypt_enc_get_block_size(pm->m_td);
    data_size = (((data.size() - 1) / block_size) + 1) * block_size;
    s = String(data_size, ReserveString);
    data_s = (unsigned char *)s.bufferSlice().ptr;
    memset(data_s, 0, data_size);
    memcpy(data_s, data.data(), data.size());
  } else { /* It's not a block algorithm */
    data_size = data.size();
    s = String(data_size, ReserveString);
    data_s = (unsigned char *)s.bufferSlice().ptr;
    memcpy(data_s, data.data(), data.size());
  }

  if (dencrypt) {
    mdecrypt_generic(pm->m_td, data_s, data_size);
  } else {
    mcrypt_generic(pm->m_td, data_s, data_size);
  }
  s.setSize(data_size);
  return s;
}
Example #8
0
String StringUtil::Implode(CArrRef items, CStrRef delim) {
    int size = items.size();
    if (size == 0) return "";

    String* sitems = (String*)smart_malloc(size * sizeof(String));
    int len = 0;
    int lenDelim = delim.size();
    int i = 0;
    for (ArrayIter iter(items); iter; ++iter) {
        new (&sitems[i]) String(iter.second().toString());
        len += sitems[i].size() + lenDelim;
        i++;
    }
    len -= lenDelim; // always one delimiter less than count of items
    assert(i == size);

    String s = String(len, ReserveString);
    char *buffer = s.mutableSlice().ptr;
    const char *sdelim = delim.data();
    char *p = buffer;
    for (int i = 0; i < size; i++) {
        String &item = sitems[i];
        if (i && lenDelim) {
            memcpy(p, sdelim, lenDelim);
            p += lenDelim;
        }
        int lenItem = item.size();
        if (lenItem) {
            memcpy(p, item.data(), lenItem);
            p += lenItem;
        }
        sitems[i].~String();
    }
    smart_free(sitems);
    assert(p - buffer == len);
    return s.setSize(len);
}
Example #9
0
static Variant php_mcrypt_do_crypt(CStrRef cipher, CStrRef key, CStrRef data,
                                   CStrRef mode, CStrRef iv, bool dencrypt) {
  MCRYPT td = mcrypt_module_open((char*)cipher.data(),
                                 (char*)MCG(algorithms_dir).data(),
                                 (char*)mode.data(),
                                 (char*)MCG(modes_dir).data());
  if (td == MCRYPT_FAILED) {
    raise_warning(MCRYPT_OPEN_MODULE_FAILED);
    return false;
  }

  /* Checking for key-length */
  int max_key_length = mcrypt_enc_get_key_size(td);
  if (key.size() > max_key_length) {
    raise_warning("Size of key is too large for this algorithm");
  }
  int count;
  int *key_length_sizes = mcrypt_enc_get_supported_key_sizes(td, &count);
  int use_key_length;
  char *key_s = NULL;
  if (count == 0 && key_length_sizes == NULL) { // all lengths 1 - k_l_s = OK
    use_key_length = key.size();
    key_s = (char*)malloc(use_key_length);
    memcpy(key_s, key.data(), use_key_length);
  } else if (count == 1) {  /* only m_k_l = OK */
    key_s = (char*)malloc(key_length_sizes[0]);
    memset(key_s, 0, key_length_sizes[0]);
    memcpy(key_s, key.data(), MIN(key.size(), key_length_sizes[0]));
    use_key_length = key_length_sizes[0];
  } else { /* dertermine smallest supported key > length of requested key */
    use_key_length = max_key_length; /* start with max key length */
    for (int i = 0; i < count; i++) {
      if (key_length_sizes[i] >= key.size() &&
          key_length_sizes[i] < use_key_length) {
        use_key_length = key_length_sizes[i];
      }
    }
    key_s = (char*)malloc(use_key_length);
    memset(key_s, 0, use_key_length);
    memcpy(key_s, key.data(), MIN(key.size(), use_key_length));
  }
  mcrypt_free(key_length_sizes);

  /* Check IV */
  char *iv_s = NULL;
  int iv_size = mcrypt_enc_get_iv_size(td);

  /* IV is required */
  if (mcrypt_enc_mode_has_iv(td) == 1) {
    if (!iv.empty()) {
      if (iv_size != iv.size()) {
        raise_warning("The IV parameter must be as long as the blocksize");
      } else {
        iv_s = (char*)malloc(iv_size + 1);
        memcpy(iv_s, iv.data(), iv_size);
      }
    } else {
      raise_warning("Attempt to use an empty IV, which is NOT recommended");
      iv_s = (char*)malloc(iv_size + 1);
      memset(iv_s, 0, iv_size + 1);
    }
  }

  int block_size;
  unsigned long int data_size;
  String s;
  char *data_s;
  /* Check blocksize */
  if (mcrypt_enc_is_block_mode(td) == 1) { /* It's a block algorithm */
    block_size = mcrypt_enc_get_block_size(td);
    data_size = (((data.size() - 1) / block_size) + 1) * block_size;
    s = String(data_size, ReserveString);
    data_s = (char*)s.mutableSlice().ptr;
    memset(data_s, 0, data_size);
    memcpy(data_s, data.data(), data.size());
  } else { /* It's not a block algorithm */
    data_size = data.size();
    s = String(data_size, ReserveString);
    data_s = (char*)s.mutableSlice().ptr;
    memcpy(data_s, data.data(), data.size());
  }

  if (mcrypt_generic_init(td, key_s, use_key_length, iv_s) < 0) {
    raise_warning("Mcrypt initialisation failed");
    return false;
  }
  if (dencrypt) {
    mdecrypt_generic(td, data_s, data_size);
  } else {
    mcrypt_generic(td, data_s, data_size);
  }

  /* freeing vars */
  mcrypt_generic_end(td);
  if (key_s != NULL) {
    free(key_s);
  }
  if (iv_s != NULL) {
    free(iv_s);
  }
  return s.setSize(data_size);
}
Example #10
0
static unsigned char *php_parserr(unsigned char *cp, unsigned char* end,
                                  querybuf *answer,
                                  int type_to_fetch, bool store,
                                  Array &subarray) {
    unsigned short type, cls ATTRIBUTE_UNUSED, dlen;
    unsigned long ttl;
    int64_t n, i;
    unsigned short s;
    unsigned char *tp, *p;
    char name[MAXHOSTNAMELEN];
    int have_v6_break = 0, in_v6_break = 0;

    n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, sizeof(name) - 2);
    if (n < 0) {
        return NULL;
    }
    cp += n;

    CHECKCP(10);
    GETSHORT(type, cp);
    GETSHORT(cls, cp);
    GETLONG(ttl, cp);
    GETSHORT(dlen, cp);
    CHECKCP(dlen);
    if (type_to_fetch != T_ANY && type != type_to_fetch) {
        cp += dlen;
        return cp;
    }

    if (!store) {
        cp += dlen;
        return cp;
    }

    subarray.set(s_host, String(name, CopyString));
    switch (type) {
    case DNS_T_A:
        CHECKCP(4);
        subarray.set(s_type, s_A);
        snprintf(name, sizeof(name), "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
        subarray.set(s_ip, String(name, CopyString));
        cp += dlen;
        break;
    case DNS_T_MX:
        CHECKCP(2);
        subarray.set(s_type, s_MX);
        GETSHORT(n, cp);
        subarray.set(s_pri, n);
    /* no break; */
    case DNS_T_CNAME:
        if (type == DNS_T_CNAME) {
            subarray.set(s_type, s_CNAME);
        }
    /* no break; */
    case DNS_T_NS:
        if (type == DNS_T_NS) {
            subarray.set(s_type, s_NS);
        }
    /* no break; */
    case DNS_T_PTR:
        if (type == DNS_T_PTR) {
            subarray.set(s_type, s_PTR);
        }
        n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2);
        if (n < 0) {
            return NULL;
        }
        cp += n;
        subarray.set(s_target, String(name, CopyString));
        break;
    case DNS_T_HINFO:
        /* See RFC 1010 for values */
        subarray.set(s_type, s_HINFO);
        CHECKCP(1);
        n = *cp & 0xFF;
        cp++;
        CHECKCP(n);
        subarray.set(s_cpu, String((const char *)cp, n, CopyString));
        cp += n;
        CHECKCP(1);
        n = *cp & 0xFF;
        cp++;
        CHECKCP(n);
        subarray.set(s_os, String((const char *)cp, n, CopyString));
        cp += n;
        break;
    case DNS_T_TXT: {
        int l1 = 0, l2 = 0;

        String s = String(dlen, ReserveString);
        tp = (unsigned char *)s.bufferSlice().ptr;

        while (l1 < dlen) {
            n = cp[l1];
            if ((n + l1) > dlen) {
                // bad record, don't set anything
                break;
            }
            memcpy(tp + l1 , cp + l1 + 1, n);
            l1 = l1 + n + 1;
            l2 = l2 + n;
        }
        s.setSize(l2);
        cp += dlen;

        subarray.set(s_type, s_TXT);
        subarray.set(s_txt, s);
        break;
    }
    case DNS_T_SOA:
        subarray.set(s_type, s_SOA);
        n = dn_expand(answer->qb2, end, cp, name, (sizeof name) -2);
        if (n < 0) {
            return NULL;
        }
        cp += n;
        subarray.set(s_mname, String(name, CopyString));
        n = dn_expand(answer->qb2, end, cp, name, (sizeof name) -2);
        if (n < 0) {
            return NULL;
        }
        cp += n;
        subarray.set(s_rname, String(name, CopyString));
        CHECKCP(5*4);
        GETLONG(n, cp);
        subarray.set(s_serial, n);
        GETLONG(n, cp);
        subarray.set(s_refresh, n);
        GETLONG(n, cp);
        subarray.set(s_retry, n);
        GETLONG(n, cp);
        subarray.set(s_expire, n);
        GETLONG(n, cp);
        subarray.set(s_minimum_ttl, n);
        break;
    case DNS_T_AAAA:
        tp = (unsigned char *)name;
        CHECKCP(8*2);
        for (i = 0; i < 8; i++) {
            GETSHORT(s, cp);
            if (s != 0) {
                if (tp > (u_char *)name) {
                    in_v6_break = 0;
                    tp[0] = ':';
                    tp++;
                }
                tp += sprintf((char *)tp, "%x", s);
            } else {
                if (!have_v6_break) {
                    have_v6_break = 1;
                    in_v6_break = 1;
                    tp[0] = ':';
                    tp++;
                } else if (!in_v6_break) {
                    tp[0] = ':';
                    tp++;
                    tp[0] = '0';
                    tp++;
                }
            }
        }
        if (have_v6_break && in_v6_break) {
            tp[0] = ':';
            tp++;
        }
        tp[0] = '\0';
        subarray.set(s_type, s_AAAA);
        subarray.set(s_ipv6, String(name, CopyString));
        break;
    case DNS_T_A6:
        p = cp;
        subarray.set(s_type, s_A6);
        CHECKCP(1);
        n = ((int)cp[0]) & 0xFF;
        cp++;
        subarray.set(s_masklen, n);
        tp = (unsigned char *)name;
        if (n > 15) {
            have_v6_break = 1;
            in_v6_break = 1;
            tp[0] = ':';
            tp++;
        }
        if (n % 16 > 8) {
            /* Partial short */
            if (cp[0] != 0) {
                if (tp > (u_char *)name) {
                    in_v6_break = 0;
                    tp[0] = ':';
                    tp++;
                }
                sprintf((char *)tp, "%x", cp[0] & 0xFF);
            } else {
                if (!have_v6_break) {
                    have_v6_break = 1;
                    in_v6_break = 1;
                    tp[0] = ':';
                    tp++;
                } else if (!in_v6_break) {
                    tp[0] = ':';
                    tp++;
                    tp[0] = '0';
                    tp++;
                }
            }
            cp++;
        }
        for (i = (n + 8)/16; i < 8; i++) {
            CHECKCP(2);
            GETSHORT(s, cp);
            if (s != 0) {
                if (tp > (u_char *)name) {
                    in_v6_break = 0;
                    tp[0] = ':';
                    tp++;
                }
                tp += sprintf((char*)tp,"%x",s);
            } else {
                if (!have_v6_break) {
                    have_v6_break = 1;
                    in_v6_break = 1;
                    tp[0] = ':';
                    tp++;
                } else if (!in_v6_break) {
                    tp[0] = ':';
                    tp++;
                    tp[0] = '0';
                    tp++;
                }
            }
        }
        if (have_v6_break && in_v6_break) {
            tp[0] = ':';
            tp++;
        }
        tp[0] = '\0';
        subarray.set(s_ipv6, String(name, CopyString));
        if (cp < p + dlen) {
            n = dn_expand(answer->qb2, end, cp, name,
                          (sizeof name) - 2);
            if (n < 0) {
                return NULL;
            }
            cp += n;
            subarray.set(s_chain, String(name, CopyString));
        }
        break;
    case DNS_T_SRV:
        CHECKCP(3*2);
        subarray.set(s_type, s_SRV);
        GETSHORT(n, cp);
        subarray.set(s_pri, n);
        GETSHORT(n, cp);
        subarray.set(s_weight, n);
        GETSHORT(n, cp);
        subarray.set(s_port, n);
        n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2);
        if (n < 0) {
            return NULL;
        }
        cp += n;
        subarray.set(s_target, String(name, CopyString));
        break;
    case DNS_T_NAPTR:
        CHECKCP(2*2);
        subarray.set(s_type, s_NAPTR);
        GETSHORT(n, cp);
        subarray.set(s_order, n);
        GETSHORT(n, cp);
        subarray.set(s_pref, n);

        CHECKCP(1);
        n = (cp[0] & 0xFF);
        ++cp;
        CHECKCP(n);
        subarray.set(s_flags, String((const char *)cp, n, CopyString));
        cp += n;

        CHECKCP(1);
        n = (cp[0] & 0xFF);
        ++cp;
        CHECKCP(n);
        subarray.set(s_services, String((const char *)cp, n, CopyString));
        cp += n;

        CHECKCP(1);
        n = (cp[0] & 0xFF);
        ++cp;
        CHECKCP(n);
        subarray.set(s_regex, String((const char *)cp, n, CopyString));
        cp += n;

        n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2);
        if (n < 0) {
            return NULL;
        }
        cp += n;
        subarray.set(s_replacement, String(name, CopyString));
        break;
    default:
        cp += dlen;
    }

    subarray.set(s_class, s_IN);
    subarray.set(s_ttl, (int)ttl);
    return cp;
}
Example #11
0
Variant binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport,
                           CArrRef fieldspec) {
  Variant ret;
  switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
      return uninit_null();
    case T_STRUCT: {
      Variant val;
      if ((val = fieldspec.rvalAt(PHPTransport::s_class)).isNull()) {
        throw_tprotocolexception("no class type in spec", INVALID_DATA);
        skip_element(T_STRUCT, transport);
        return uninit_null();
      }
      String structType = val.toString();
      ret = createObject(structType);
      if (ret.isNull()) {
        // unable to create class entry
        skip_element(T_STRUCT, transport);
        return uninit_null();
      }
      Variant spec = f_hphp_get_static_property(structType, s_TSPEC);
      if (!spec.is(KindOfArray)) {
        char errbuf[128];
        snprintf(errbuf, 128, "spec for %s is wrong type: %d\n",
                 structType.data(), ret.getType());
        throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
        return uninit_null();
      }
      binary_deserialize_spec(ret.toObject(), transport, spec.toArray());
      return ret;
    } break;
    case T_BOOL: {
      uint8_t c;
      transport.readBytes(&c, 1);
      return c != 0;
    }
  //case T_I08: // same numeric value as T_BYTE
    case T_BYTE: {
      uint8_t c;
      transport.readBytes(&c, 1);
      return Variant((int8_t)c);
    }
    case T_I16: {
      uint16_t c;
      transport.readBytes(&c, 2);
      return Variant((int16_t)ntohs(c));
    }
    case T_I32: {
      uint32_t c;
      transport.readBytes(&c, 4);
      return Variant((int32_t)ntohl(c));
    }
    case T_U64:
    case T_I64: {
      uint64_t c;
      transport.readBytes(&c, 8);
      return Variant((int64_t)ntohll(c));
    }
    case T_DOUBLE: {
      union {
        uint64_t c;
        double d;
      } a;
      transport.readBytes(&(a.c), 8);
      a.c = ntohll(a.c);
      return a.d;
    }
    //case T_UTF7: // aliases T_STRING
    case T_UTF8:
    case T_UTF16:
    case T_STRING: {
      uint32_t size = transport.readU32();
      if (size && (size + 1)) {
        String s = String(size, ReserveString);
        char* strbuf = s.mutableSlice().ptr;
        transport.readBytes(strbuf, size);
        return s.setSize(size);
      } else {
        return "";
      }
    }
    case T_MAP: { // array of key -> value
      uint8_t types[2];
      transport.readBytes(types, 2);
      uint32_t size = transport.readU32();

      Array keyspec = fieldspec.rvalAt(PHPTransport::s_key,
                                       AccessFlags::Error_Key).toArray();
      Array valspec = fieldspec.rvalAt(PHPTransport::s_val,
                                       AccessFlags::Error_Key).toArray();
      ret = Array::Create();

      for (uint32_t s = 0; s < size; ++s) {
        Variant key = binary_deserialize(types[0], transport, keyspec);
        Variant value = binary_deserialize(types[1], transport, valspec);
        ret.set(key, value);
      }
      return ret; // return_value already populated
    }
    case T_LIST: { // array with autogenerated numeric keys
      int8_t type = transport.readI8();
      uint32_t size = transport.readU32();
      Variant elemvar = fieldspec.rvalAt(PHPTransport::s_elem,
                                         AccessFlags::Error_Key);
      Array elemspec = elemvar.toArray();
      ret = Array::Create();

      for (uint32_t s = 0; s < size; ++s) {
        Variant value = binary_deserialize(type, transport, elemspec);
        ret.append(value);
      }
      return ret;
    }
    case T_SET: { // array of key -> TRUE
      uint8_t type;
      uint32_t size;
      transport.readBytes(&type, 1);
      transport.readBytes(&size, 4);
      size = ntohl(size);
      Variant elemvar = fieldspec.rvalAt(PHPTransport::s_elem,
                                         AccessFlags::Error_Key);
      Array elemspec = elemvar.toArray();
      ret = Array::Create();

      for (uint32_t s = 0; s < size; ++s) {
        Variant key = binary_deserialize(type, transport, elemspec);

        if (key.isInteger()) {
          ret.set(key, true);
        } else {
          ret.set(key.toString(), true);
        }
      }
      return ret;
    }
  };

  char errbuf[128];
  sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
  throw_tprotocolexception(String(errbuf, CopyString), INVALID_DATA);
  return uninit_null();
}