Example #1
0
String f_exec(CStrRef command, Variant output /* = null */,
              Variant return_var /* = null */) {
  ShellExecContext ctx;
  FILE *fp = ctx.exec(command);
  if (!fp) return "";
  StringBuffer sbuf;
  sbuf.read(fp);

  Array lines = StringUtil::Explode(sbuf.detach(), "\n");
  return_var = ctx.exit();
  int count = lines.size();
  if (count > 0 && lines[count - 1].toString().empty()) {
    count--; // remove explode()'s last empty line
  }
  if (!output.is(KindOfArray)) {
    output = Array(ArrayData::Create());
  }

  for (int i = 0; i < count; i++) {
    output.append(lines[i]);
  }

  if (!count || lines.empty()) {
    return String();
  }
  return StringUtil::Trim(lines[count - 1], StringUtil::TrimRight);
}
bool TestCppBase::TestVariant() {
  // operators
  {
    Variant v(15);
    v += 20;
    VERIFY(v.isNumeric());
    VERIFY(v.is(KindOfInt64));
    VERIFY(v == Variant(35));
  }

  // conversions
  {
    Variant v("123");
    VERIFY(v.toInt32() == 123);
  }

  // offset
  {
    Variant v = "test";
    VS(v.rvalAt(0), "t");
  }
  {
    Variant v;
    v.lvalAt(0) = String("v0");
    v.lvalAt(1) = String("v1");
    VERIFY(v[0] == "v0");
    VERIFY(v[1] == "v1");
  }
  {
    Variant v;
    v.lvalAt() = String("test");
    VS(v, CREATE_VECTOR1("test"));
  }
  {
    Variant v;
    v.lvalAt(1) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }
  {
    Variant v;
    v.lvalAt(Variant(1.5)) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }
  {
    Variant v;
    v.lvalAt(s_1) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }
  {
    Variant v;
    v.lvalAt(Variant("1")) = String("test");
    VS(v[1], "test");
    VS(v[1.5], "test");
    VS(v[Variant(1.5)], "test");
    VS(v[s_1], "test");
    VS(v[Variant("1")], "test");
  }

  // membership
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(s_n1) = String("v1");
    v.remove(s_n1);
    VS(v, CREATE_MAP1(s_n0, "v0"));
    v.append("v2");
    VS(v, CREATE_MAP2(s_n0, "v0", 0, "v2"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(1) = String("v1");
    v.remove(Variant(1.5));
    VS(v, CREATE_MAP1("n0", "v0"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(1) = String("v1");
    v.remove(Variant("1"));
    VS(v, CREATE_MAP1("n0", "v0"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(1) = String("v1");
    v.remove(String("1"));
    VS(v, CREATE_MAP1("n0", "v0"));
  }
  {
    Variant v;
    v.lvalAt(s_n0) = String("v0");
    v.lvalAt(empty_string) = String("v1");
    v.remove(Variant());
    VS(v, CREATE_MAP1("n0", "v0"));
  }

  // references
  {
    Variant v1("original");
    Variant v2 = v1;
    v2 = String("changed");
    VERIFY(v1 == "original");
  }
  {
    Variant v1("original");
    Variant v2 = strongBind(v1);
    v2 = String("changed");
    VERIFY(v1 == "changed");
  }
  {
    Variant v1 = 10;
    Variant v2 = Array(ArrayInit(1).setRef(v1).create());
    v1 = 20;
    VS(v2[0], 20);
  }
  {
    Variant v1 = 10;
    Variant v2;
    v2.lvalAt() = ref(v1);
    v1 = 20;
    VS(v2[0], 20);
  }
  {
    Variant v1 = 10;
    Variant v2 = CREATE_VECTOR1(5);
    v2.lvalAt() = ref(v1);
    v1 = 20;
    VS(v2[1], 20);
  }
  {
    Variant v1 = 10;
    Variant v2 = strongBind(v1);
    v2++;
    VS(v2, 11);
    VS(v1, 11);
  }
  {
    Variant arr = CREATE_VECTOR2(1, 2);
    Variant v;
    for (MutableArrayIter iter = arr.begin(nullptr, v); iter.advance();) {
      v++;
    }
    VS(arr, CREATE_VECTOR2(2, 3));
  }

  // array escalation
  {
    Variant arr;
    lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr;
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create();
    lval(arr.lvalAt(0)).lvalAt(0) = 1.2;
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create();
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP1(s_name, CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create("test");
    arr.lvalAt(0) = CREATE_VECTOR1(1.2);
    VS(arr, CREATE_VECTOR1(CREATE_VECTOR1(1.2)));
  }
  {
    Variant arr = Array::Create("test");
    lval(arr.lvalAt(s_name)).lvalAt(0) = 1.2;
    VS(arr, CREATE_MAP2(0, "test", s_name, CREATE_VECTOR1(1.2)));
  }

  return Count(true);
}
Example #3
0
/* SOAP client calls this function to parse response from SOAP server */
bool parse_packet_soap(c_SoapClient *obj, const char *buffer,
                       int buffer_size, sdlFunctionPtr fn, const char *fn_name,
                       Variant &return_value, Variant &soap_headers) {
  char* envelope_ns = NULL;
  xmlNodePtr trav, env, head, body, resp, cur, fault;
  xmlAttrPtr attr;
  int param_count = 0;
  int soap_version = SOAP_1_1;
  sdlSoapBindingFunctionHeaderMap *hdrs = NULL;

  return_value.reset();

  /* Response for one-way opearation */
  if (buffer_size == 0) {
    return true;
  }

  /* Parse XML packet */
  xmlDocPtr response = soap_xmlParseMemory(buffer, buffer_size);
  if (!response) {
    add_soap_fault(obj, "Client", "looks like we got no XML document");
    return false;
  }
  if (xmlGetIntSubset(response) != NULL) {
    add_soap_fault(obj, "Client", "DTD are not supported by SOAP");
    xmlFreeDoc(response);
    return false;
  }

  /* Get <Envelope> element */
  env = NULL;
  trav = response->children;
  while (trav != NULL) {
    if (trav->type == XML_ELEMENT_NODE) {
      if (!env && node_is_equal_ex(trav,"Envelope", SOAP_1_1_ENV_NAMESPACE)) {
        env = trav;
        envelope_ns = SOAP_1_1_ENV_NAMESPACE;
        soap_version = SOAP_1_1;
      } else if (!env &&
                 node_is_equal_ex(trav, "Envelope", SOAP_1_2_ENV_NAMESPACE)) {
        env = trav;
        envelope_ns = SOAP_1_2_ENV_NAMESPACE;
        soap_version = SOAP_1_2;
      } else {
        add_soap_fault(obj, "VersionMismatch", "Wrong Version");
        xmlFreeDoc(response);
        return false;
      }
    }
    trav = trav->next;
  }
  if (env == NULL) {
    add_soap_fault(obj, "Client",
                   "looks like we got XML without \"Envelope\" element");
    xmlFreeDoc(response);
    return false;
  }

  attr = env->properties;
  while (attr != NULL) {
    if (attr->ns == NULL) {
      add_soap_fault(obj, "Client",
                     "A SOAP Envelope element cannot have non Namespace "
                     "qualified attributes");
      xmlFreeDoc(response);
      return false;
    }
    if (attr_is_equal_ex(attr, "encodingStyle", SOAP_1_2_ENV_NAMESPACE)) {
      if (soap_version == SOAP_1_2) {
        add_soap_fault(obj, "Client",
                       "encodingStyle cannot be specified on the Envelope");
        xmlFreeDoc(response);
        return false;
      }
      if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE)) {
        add_soap_fault(obj, "Client", "Unknown data encoding style");
        xmlFreeDoc(response);
        return false;
      }
    }
    attr = attr->next;
  }

  /* Get <Header> element */
  head = NULL;
  trav = env->children;
  while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    trav = trav->next;
  }
  if (trav != NULL && node_is_equal_ex(trav,"Header",envelope_ns)) {
    head = trav;
    trav = trav->next;
  }

  /* Get <Body> element */
  body = NULL;
  while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    trav = trav->next;
  }
  if (trav != NULL && node_is_equal_ex(trav,"Body",envelope_ns)) {
    body = trav;
    trav = trav->next;
  }
  while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    trav = trav->next;
  }
  if (body == NULL) {
    add_soap_fault(obj, "Client", "Body must be present in a SOAP envelope");
    xmlFreeDoc(response);
    return false;
  }
  attr = body->properties;
  while (attr != NULL) {
    if (attr->ns == NULL) {
      if (soap_version == SOAP_1_2) {
        add_soap_fault(obj, "Client",
                       "A SOAP Body element cannot have non Namespace "
                       "qualified attributes");
        xmlFreeDoc(response);
        return false;
      }
    } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
      if (soap_version == SOAP_1_2) {
        add_soap_fault(obj, "Client",
                       "encodingStyle cannot be specified on the Body");
        xmlFreeDoc(response);
        return false;
      }
      if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE)) {
        add_soap_fault(obj, "Client", "Unknown data encoding style");
        xmlFreeDoc(response);
        return false;
      }
    }
    attr = attr->next;
  }
  if (trav != NULL && soap_version == SOAP_1_2) {
    add_soap_fault(obj, "Client",
                   "A SOAP 1.2 envelope can contain only Header and Body");
    xmlFreeDoc(response);
    return false;
  }

  if (head != NULL) {
    attr = head->properties;
    while (attr != NULL) {
      if (attr->ns == NULL) {
        add_soap_fault(obj, "Client",
                       "A SOAP Header element cannot have non Namespace "
                       "qualified attributes");
        xmlFreeDoc(response);
        return false;
      }
      if (attr_is_equal_ex(attr, "encodingStyle", SOAP_1_2_ENV_NAMESPACE)) {
        if (soap_version == SOAP_1_2) {
          add_soap_fault(obj, "Client",
                         "encodingStyle cannot be specified on the Header");
          xmlFreeDoc(response);
          return false;
        }
        if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE)) {
          add_soap_fault(obj, "Client", "Unknown data encoding style");
          xmlFreeDoc(response);
          return false;
        }
      }
      attr = attr->next;
    }
  }

  /* Check if <Body> contains <Fault> element */
  fault = get_node_ex(body->children,"Fault",envelope_ns);
  if (fault != NULL) {
    char *faultcode = NULL;
    String faultstring, faultactor;
    Variant details;
    xmlNodePtr tmp;

    if (soap_version == SOAP_1_1) {
      tmp = get_node(fault->children, "faultcode");
      if (tmp != NULL && tmp->children != NULL) {
        faultcode = (char*)tmp->children->content;
      }

      tmp = get_node(fault->children, "faultstring");
      if (tmp != NULL && tmp->children != NULL) {
        Variant zv = master_to_zval(get_conversion(KindOfString), tmp);
        faultstring = zv.toString();
      }

      tmp = get_node(fault->children, "faultactor");
      if (tmp != NULL && tmp->children != NULL) {
        Variant zv = master_to_zval(get_conversion(KindOfString), tmp);
        faultactor = zv.toString();
      }

      tmp = get_node(fault->children, "detail");
      if (tmp != NULL) {
        details = master_to_zval(encodePtr(), tmp);
      }
    } else {
      tmp = get_node(fault->children, "Code");
      if (tmp != NULL && tmp->children != NULL) {
        tmp = get_node(tmp->children, "Value");
        if (tmp != NULL && tmp->children != NULL) {
          faultcode = (char*)tmp->children->content;
        }
      }

      tmp = get_node(fault->children,"Reason");
      if (tmp != NULL && tmp->children != NULL) {
        /* TODO: lang attribute */
        tmp = get_node(tmp->children,"Text");
        if (tmp != NULL && tmp->children != NULL) {
          Variant zv = master_to_zval(get_conversion(KindOfString), tmp);
          faultstring = zv.toString();
        }
      }

      tmp = get_node(fault->children,"Detail");
      if (tmp != NULL) {
        details = master_to_zval(encodePtr(), tmp);
      }
    }
    obj->m_soap_fault =
      Object(SystemLib::AllocSoapFaultObject(String(faultcode, CopyString),
                                             faultstring, faultactor, details));
    xmlFreeDoc(response);
    return false;
  }

  /* Parse content of <Body> element */
  return_value = Array::Create();
  resp = body->children;
  while (resp != NULL && resp->type != XML_ELEMENT_NODE) {
    resp = resp->next;
  }
  if (resp != NULL) {
    if (fn && fn->binding && fn->binding->bindingType == BINDING_SOAP) {
      /* Function has WSDL description */
      sdlParamPtr h_param, param;
      xmlNodePtr val = NULL;
      const char *name, *ns = NULL;
      Variant tmp;
      sdlSoapBindingFunctionPtr fnb =
        (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
      int res_count;

      hdrs = &fnb->output.headers;

      if (!fn->responseParameters.empty()) {
        res_count = fn->responseParameters.size();
        for (unsigned int i = 0; i < fn->responseParameters.size(); i++) {
          h_param = fn->responseParameters[i];
          param = h_param;
          if (fnb->style == SOAP_DOCUMENT) {
            if (param->element) {
              name = param->element->name.c_str();
              ns = param->element->namens.c_str();
/*
              name = param->encode->details.type_str;
              ns = param->encode->details.ns;
*/
            } else {
              name = param->paramName.c_str();
            }
          } else {
            name = fn->responseName.c_str();
            /* ns = ? */
          }

          /* Get value of parameter */
          cur = get_node_ex(resp, (char*)name, (char*)ns);
          if (!cur) {
            cur = get_node(resp, (char*)name);
            /* TODO: produce warning invalid ns */
          }
          if (!cur && fnb->style == SOAP_RPC) {
            cur = resp;
          }
          if (cur) {
            if (fnb->style == SOAP_DOCUMENT) {
              val = cur;
            } else {
              val = get_node(cur->children, (char*)param->paramName.c_str());
              if (res_count == 1) {
                if (val == NULL) {
                  val = get_node(cur->children, "return");
                }
                if (val == NULL) {
                  val = get_node(cur->children, "result");
                }
                if (val == NULL && cur->children && !cur->children->next) {
                  val = cur->children;
                }
              }
            }
          }

          if (!val) {
            /* TODO: may be "nil" is not OK? */
            tmp.reset();
/*
            add_soap_fault(obj, "Client", "Can't find response data");
            xmlFreeDoc(response);
            return false;
*/
          } else {
            /* Decoding value of parameter */
            if (param != NULL) {
              tmp = master_to_zval(param->encode, val);
            } else {
              tmp = master_to_zval(encodePtr(), val);
            }
          }
          return_value.set(String(param->paramName), tmp);
          param_count++;
        }
      }
    } else {
      /* Function hasn't WSDL description */
      xmlNodePtr val;
      val = resp->children;
      while (val != NULL) {
        while (val && val->type != XML_ELEMENT_NODE) {
          val = val->next;
        }
        if (val != NULL) {
          if (!node_is_equal_ex(val,"result",RPC_SOAP12_NAMESPACE)) {
            Variant tmp = master_to_zval(encodePtr(), val);
            if (val->name) {
              String key((char*)val->name, CopyString);
              if (return_value.toArray().exists(key)) {
                return_value.lvalAt(key).append(tmp);
              } else if (val->next && get_node(val->next, (char*)val->name)) {
                Array arr = Array::Create();
                arr.append(tmp);
                return_value.set(key, arr);
              } else {
                return_value.set(key, tmp);
              }
            } else {
              return_value.append(tmp);
            }
            ++param_count;
          }
          val = val->next;
        }
      }
    }
  }

  if (return_value.isArray()) {
    if (param_count == 0) {
      return_value.reset();
    } else if (param_count == 1) {
      Array arr = return_value.toArray();
      ArrayIter iter(arr);
      return_value = iter.second();
    }
  }

  if (head) {
    trav = head->children;
    while (trav) {
      if (trav->type == XML_ELEMENT_NODE) {
        encodePtr enc;
        if (hdrs && !hdrs->empty()) {
          string key;
          if (trav->ns) {
            key += (char*)trav->ns->href;
            key += ':';
          }
          key += (char*)trav->name;
          sdlSoapBindingFunctionHeaderMap::const_iterator iter =
            hdrs->find(key);
          if (iter != hdrs->end()) {
            enc = iter->second->encode;
          }
        }
        soap_headers.set(String((char*)trav->name, CopyString),
                         master_to_zval(enc, trav));
      }
      trav = trav->next;
    }
  }

  xmlFreeDoc(response);
  return true;
}
Example #4
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, false);
      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_FLOAT: {
      union {
        uint32_t c;
        float d;
      } a;
      transport.readBytes(&(a.c), 4);
      a.c = ntohl(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.bufferSlice().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();
}