示例#1
0
void readRelocations(
  FILE* relocFile,
  std::set<TCA>* liveStubs,
  void (*callback)(TransRelocInfo&& tri, void* data),
  void* data) {
  std::string line;
  uint64_t addr;
  uint64_t end;

  while (readLine(line, relocFile)) {
    int n;
    if (sscanf(line.c_str(), "%" SCNx64 " %" SCNx64 "%n",
               &addr, &end, &n) >= 2) {
      auto pos = line.rfind(' ');
      if (pos == n) {
        if (liveStubs && !end) {
          if (!strcmp("NewStub", line.c_str() + pos + 1)) {
            liveStubs->insert((TCA)addr);
          } else if (!strcmp("FreeStub", line.c_str() + pos + 1)) {
            liveStubs->erase((TCA)addr);
          }
        }
        continue;
      }
      assert(pos != std::string::npos && pos > n);
      auto b64 = line.substr(pos + 1);
      String decoded = string_base64_decode(b64.c_str(), b64.size(), true);

      BlobDecoder blob(decoded.data(), decoded.size());
      TransRelocInfoHelper trih;
      blob(trih);

      TransRelocInfo tri(trih.toTRI(code()));
      tri.start = reinterpret_cast<TCA>(addr);
      tri.end = reinterpret_cast<TCA>(end);
      x64::findFixups(tri.start, tri.end, tri.fixups);

      callback(std::move(tri), data);
    }
  }
}
String StringUtil::Base64Decode(CStrRef input, bool strict /* = false */) {
  int len = input.size();
  char *ret = string_base64_decode(input.data(), len, strict);
  return String(ret, len, AttachString);
}
示例#3
0
String StringUtil::Base64Decode(const String& input,
                                bool strict /* = false */) {
  int len = input.size();
  return string_base64_decode(input.data(), len, strict);
}
示例#4
0
File* DataStreamWrapper::open(const String& filename, const String& mode,
                              int options, const Variant& context) {

  // @todo: check allow_url_include?

  const char* data = filename.data();
  int data_len = filename.length();
  bool base64 = false;
  if (strncmp(data, "data:", sizeof("data:") - 1)) {
    return nullptr;
  }
  data += sizeof("data:") - 1;
  data_len -= sizeof("data:") - 1;

  // RFC 2397 specifies 'data:' as the prefix,
  // but zend's PHP supports 'data://' as well
  if (data_len >= 2 && data[0] == '/' && data[1] == '/') {
    data_len -= 2;
    data += 2;
  }

  char* comma = (char*)memchr(data, ',', data_len);
  if (comma == nullptr) {
    raise_warning("rfc2397: missing comma");
    return nullptr;
  }

  if (comma != data) {
    // we have meta
    ssize_t meta_len = comma - data;
    data_len -= meta_len;
    char* semi = (char*)memchr(data, ';', meta_len);
    char* slash = (char*)memchr(data, '/', meta_len);

    if (!slash && !semi) {
      raise_warning("rfc2397: invalid meta data");
      return nullptr;
    }

    if (!semi) {
      // only media type (type/subtype,data)
      ssize_t media_len = comma - data;
      meta_len -= media_len;
      data += media_len;
    } else if (slash && slash < semi) {
      // media type + param (type/subtype;param,data)
      ssize_t media_len = semi - data;
      meta_len -= media_len;
      data += media_len;
    } else {
      // no media type (;base64,data)
      if (semi != data // ex. foo;base64,data
          || meta_len != sizeof(";base64") - 1 // ex. ;something,data
          || memcmp(data, ";base64",
                    sizeof(";base64") - 1)) { // ex. ;base65,data
          raise_warning("rfc2397: invalid meta data");
          return nullptr;
        }
    }

    assert(data == comma || data == semi);
    // eat parameters, and figure out if we have ';base64'
    while (semi && (data == semi)) {
      data++;
      meta_len--;
      char* equals = (char*)memchr(data, '=', meta_len);
      semi = (char*)memchr(data, ';', meta_len);
      if (!equals || (semi && semi < data)) {
        // no equals, so either 'base64' or its bad
        if (meta_len != sizeof("base64") - 1 ||
            memcmp(data, "base64", sizeof("base64")-1)) {
          raise_warning("rfc2396: invalid parameter");
          return nullptr;
        }
        // it's "base64", we're done
        base64 = true;
        meta_len -= sizeof("base64") - 1;
        data += sizeof("base64") - 1;
        break;
      }
      // there's a parameter
      if (semi) {
        meta_len -= semi - data + 1;
        data = semi;
      } /* else, we're done with meta */
    }
  }
  data = comma + 1;
  data_len -= 1;
  std::unique_ptr<MemFile> file;
  String decoded;

  if (base64) {
    decoded = string_base64_decode(data, data_len, true);
    if (decoded.isNull()) {
      raise_warning("unable to decode base64 data");
      return nullptr;
    }
  } else {
    decoded = url_decode(data, data_len);
  }
  file =
    std::unique_ptr<MemFile>(NEWOBJ(MemFile)(decoded.data(), decoded.size()));
  return file.release();
}