Ejemplo n.º 1
0
void PPLet::do_next(xqp_tuple &t)
{
    if (need_reopen)
    {
        if (!seq_filled) source_child.op->reopen();
        seq_filled = false;
        s->clear();
        first_time = true;
        need_reopen = false;
        reinit_consumer_table();
    }

    if(first_time && need_to_check_type)
    {
       if(!type_matches(source_child, s, source, seq_filled, st))
          throw XQUERY_EXCEPTION2(XPTY0004, "Type of a value bound to the variable does not match the declared type according to the rules for SequenceType matching.");
       first_time = false;	
    }

    data_child.op->next(t);

    if (t.is_eos()) need_reopen = true;
}
Ejemplo n.º 2
0
void process_proguard_rules(const ProguardConfiguration& pg_config,
                            ProguardMap* proguard_map,
                            Scope& classes) {
  for (const auto& cls : classes) {
    auto cname = cls->get_type()->get_name()->c_str();
    auto cls_len = strlen(cname);
    TRACE(PGR, 8, "Examining class %s\n", cname);
    for (const auto& k : pg_config.keep_rules) {
		  auto keep_name = dextype_from_dotname(k.class_spec.className);
      std::string translated_keep_name = proguard_map->translate_class(keep_name);
      TRACE(PGR,
            8,
            "==> Checking against keep rule for %s (%s)\n",
            keep_name.c_str(), translated_keep_name.c_str());
      if (type_matches(translated_keep_name.c_str(),
                       cname,
                       translated_keep_name.size(),
                       cls_len)) {
				TRACE(PGR, 8, "Setting keep for %s\n", cname);
        cls->rstate.set_keep();
      }
    }
  }
}
Ejemplo n.º 3
0
static int
_info_list(void)
{
   Eina_Iterator *itr;
   Eina_List *types;
   const Eina_Hash_Tuple *tuple;
   const Eina_List *l;
   const char *name, *last_module;
   Eina_Bool module_found = EINA_FALSE, type_found = EINA_FALSE;
   Eina_Bool in_module = EINA_FALSE;

   EINA_LIST_FOREACH(modules, l, name)
     {
        if (!module_matches(name))
          {
             DBG("filter out module '%s': does not match '%s'",
                 name, module_patterns_str);
             continue;
          }

        if (!edje_module_load(name))
          {
             ERR("error loading external '%s'", name);
             continue;
          }

        module_found = EINA_TRUE;
     }

   itr = edje_external_iterator_get();
   types = NULL;
   EINA_ITERATOR_FOREACH(itr, tuple)
     {
        const Edje_External_Type *type = tuple->data;
        name = tuple->key;

        if (!type)
          {
             ERR("no type value for '%s'", name);
             continue;
          }
        else if (type->abi_version != edje_external_type_abi_version_get())
          {
             ERR("type '%s' with incorrect abi_version %u (expected %u)",
                 name, type->abi_version, edje_external_type_abi_version_get());
             continue;
          }

        if (!type_matches(name))
          {
             DBG("filter out type '%s': does not match '%s'", name, type_glob);
             continue;
          }

        types = eina_list_append(types, tuple);
        type_found = EINA_TRUE;
     }
   eina_iterator_free(itr);

   last_module = NULL;
   types = eina_list_sort(types, 0, _types_sort);
   EINA_LIST_FREE(types, tuple)
     {
        Eina_Bool changed_module = EINA_FALSE;
        const Edje_External_Type *type = tuple->data;
        const Edje_External_Param_Info *param;
        name = tuple->key;

        if ((last_module) && (type->module))
          {
             changed_module = ((last_module != type->module) &&
                               (!strcmp(last_module, type->module)));
          }
        else if ((!last_module) && (type->module))
          changed_module = EINA_TRUE;

        if (changed_module)
          {
             if (in_module)
               {
                  if (machine) puts("TYPES-END\nMODULE-END");
                  else puts(INDENT "}\n}");
               }

             if (machine)
               printf("MODULE-BEGIN\n"
                      "NAME: %s\n"
                      "FRIENDLY-NAME: %s\n"
                      "TYPES-BEGIN\n",
                      type->module, type->module_name);
             else
               printf("module {\n"
                      INDENT "name: \"%s\";\n"
                      INDENT "friendly_name: \"%s\";\n"
                      INDENT "types {\n",
                      type->module, type->module_name);

             in_module = EINA_TRUE;
          }

        if (machine) printf("TYPE-BEGIN\nNAME: %s\n", name);
        else printf(INDENT2 "type {\n" INDENT3 "name: \"%s\";\n", name);

        if (detail > 1)
          {
             const char *str;

             if (!type->label_get) str = NULL;
             else str = type->label_get(type->data);
             if (machine) printf("LABEL: %s\n", str ? str : "");
             else if (str) printf(INDENT3 "label: \"%s\";\n", str);

             if (!type->description_get) str = NULL;
             else str = type->description_get(type->data);
             if (machine) printf("DESCRIPTION: %s\n", str ? str : "");
             else if (str) printf(INDENT3 "description: \"%s\";\n", str);
          }

        if (machine) puts("PARAMS-BEGIN");
        else puts(INDENT3 "params {");

        for (param = type->parameters_info; param->name != NULL; param++)
          {
             const char *pt = _param_type_str_get(param);
             char buf[128];

             if (machine)
               printf("PARAM-BEGIN\nNAME: %s\nTYPE: %s\n", param->name, pt);
             else printf(INDENT4 "%s: \"%s\"", pt, param->name);

             if (detail > 0)
               {
                  const char *str = _param_value_str_get
                    (type, param, buf, sizeof(buf));
                  if (machine) printf("DEFAULT: %s\n", str ? str : "");
                  else if (str) printf(" \"%s\"", str);

                  if (detail > 1)
                    {
                       if (!machine) putchar(';');
                       _param_extra_details(type, param);
                    }
               }

             if (machine) puts("PARAM-END");
             else if (detail > 1) putchar('\n');
             else puts(";");
          }

        if (machine) puts("PARAMS-END\nTYPE-END");
        else puts(INDENT3 "}\n" INDENT2 "}");

        last_module = type->module;
     }
Ejemplo n.º 4
0
/*
 * Initializes list of classes that are reachable via reflection, and calls
 * or from code.
 *
 * These include:
 *  - Classes used in the manifest (e.g. activities, services, etc)
 *  - View or Fragment classes used in layouts
 *  - Classes that are in certain packages (specified in the reflected_packages
 *    section of the config) and classes that extend from them
 *  - Classes marked with special annotations (keep_annotations in config)
 *  - Classes reachable from native libraries
 */
static void init_permanently_reachable_classes(const Scope& scope, folly::dynamic& config, const std::vector<KeepRule>& proguard_rules) {

  std::string apk_dir;
  std::vector<std::string> reflected_package_names;

  auto config_apk_dir = config.find("apk_dir");
  if (config_apk_dir != config.items().end()) {
    apk_dir = toStdString(config_apk_dir->second.asString());
  }

  auto config_reflected_package_names = config.find("reflected_packages");
  if (config_reflected_package_names != config.items().end()) {
    for (auto config_pkg_name : config_reflected_package_names->second) {
      std::string pkg_name = toStdString(config_pkg_name.asString());
      reflected_package_names.push_back(pkg_name);
    }
  }

  std::unordered_set<DexType*> keep_annotations;
  auto config_keep_annotations = config.find("keep_annotations");
  if (config_keep_annotations != config.items().end()) {
    for (auto const& config_anno_name : config_keep_annotations->second) {
      std::string anno_name = toStdString(config_anno_name.asString());
      DexType* anno = DexType::get_type(anno_name.c_str());
      if (anno) keep_annotations.insert(anno);
    }
  }
  keep_annotated_classes(scope, keep_annotations);

  std::vector<std::string> keep_pkgs;
  auto config_keep_packages = config.find("keep_packages");
  if (config_keep_packages != config.items().end()) {
    for (auto const& config_pkg : config_keep_packages->second) {
      auto pkg_name = toStdString(config_pkg.asString());
      keep_pkgs.push_back(pkg_name);
    }
  }
  keep_packages(scope, keep_pkgs);

  if (apk_dir.size()) {
    // Classes present in manifest
    std::string manifest = apk_dir + std::string("/AndroidManifest.xml");
    for (std::string classname : get_manifest_classes(manifest)) {
      mark_reachable_by_classname(classname, false);
    }

    // Classes present in XML layouts
    for (std::string classname : get_layout_classes(apk_dir)) {
      mark_reachable_by_classname(classname, false);
    }

    // Classnames present in native libraries (lib/*/*.so)
    for (std::string classname : get_native_classes(apk_dir)) {
      mark_reachable_by_classname(classname, false);
    }
  }

  std::unordered_set<DexClass*> reflected_package_classes;
  for (auto clazz : scope) {
    const char* cname = clazz->get_type()->get_name()->c_str();
    for (auto pkg : reflected_package_names) {
      if (starts_with(cname, pkg.c_str())) {
        reflected_package_classes.insert(clazz);
        continue;
      }
    }
  }
  for (auto clazz : scope) {
    if (in_reflected_pkg(clazz, reflected_package_classes)) {
      reflected_package_classes.insert(clazz);
      /* Note:
       * Some of these are by string, others by type
       * but we have no way in the config to distinguish
       * them currently.  So, we mark with the most
       * conservative sense here.
       */
      mark_reachable_by_classname(clazz, false);
    }
  }

  /* Do only keep class rules for now.
   * '*' and '**' rules are skipped,
   * because those are matching on something else,
   * which we haven't implemented yet.
   * Rules can be "*" or "**" on classname and match
   * on some other attribute. We don't match against
   * all attributes at once, so this prevents us
   * from matching everything.
   */
  std::vector<std::string> cls_patterns;
  for (auto const& r : proguard_rules) {
    if (r.classname != nullptr &&
        r.class_type == keeprules::ClassType::CLASS &&
          strlen(r.classname) > 2) {
      std::string cls_pattern(r.classname);
      std::replace(cls_pattern.begin(), cls_pattern.end(), '.', '/');
      auto prep_pat = 'L' + cls_pattern;
      TRACE(PGR, 1, "adding pattern %s \n", prep_pat.c_str());
      cls_patterns.push_back(prep_pat);
    }
  }
  size_t pg_marked_classes = 0;
  for (auto clazz : scope) {
    auto cname = clazz->get_type()->get_name()->c_str();
    auto cls_len = strlen(cname);
    for (auto const& pat : cls_patterns) {
        int pat_len = pat.size();
        if (type_matches(pat.c_str(), cname, pat_len, cls_len)) {
          mark_reachable_directly(clazz);
          TRACE(PGR, 2, "matched cls %s against pattern %s \n", cname, pat.c_str());
          pg_marked_classes++;
          break;
      }
    }
  }
  TRACE(PGR, 1, "matched on %lu classes with CLASS KEEP proguard rules \n",
      pg_marked_classes);
}