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; }
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(); } } } }
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; }
/* * 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); }