1212#include < errno.h>
1313#include < stdbool.h>
1414
15+ #include < rapidxml.hpp>
16+
1517static const std::string packages_path = " /data/system/packages.xml" ;
1618static std::vector<char > LoadFileToStdVector (std::string filename);
1719
18- extern " C" bool get_pkg_from_classpath_arg (const char * classpath_dir, char * package_name, size_t package_name_buffer_size) {
20+ // !!! DO NOT REMOVE THIS FUNCTION UNLESS YOU ADDED IT IN RAPIDXML !!!
21+ void rapidxml::parse_error_handler (const char *what, void *where) {
22+ LOGE (" rapidxml Parser error: %s, Start of string: %s\n " , what, (char *) where);
23+ }
24+
25+ extern " C" bool get_pkg_from_classpath_arg (const char * classpath_dir, char * package_name, size_t package_name_buffer_size) {
1926 size_t dir_len = strlen (classpath_dir);
2027 if (dir_len == 0 || dir_len >= 1024 ) {
2128 LOGE (" Invalid classpath dir length: %zu" , dir_len);
@@ -24,13 +31,60 @@ extern "C" bool get_pkg_from_classpath_arg(const char* classpath_dir, char* pack
2431
2532 std::vector<char > packagesFile = LoadFileToStdVector (packages_path);
2633
27- if (packagesFile.size () < 1 )
28- {
34+ if (packagesFile.empty ()) {
2935 LOGE (" Failed to read packages.xml: %s" , strerror (errno));
3036 return false ;
3137 }
32-
33- AbxDecoder decoder (packagesFile);
38+
39+ AbxDecoder decoder (&packagesFile);
40+ if (!decoder.isAbx ()) {
41+ LOGD (" This file is not ABX encoded, trying with XML fallback" );
42+
43+ rapidxml::xml_document document;
44+ document.parse <0 >(packagesFile.data ());
45+
46+ rapidxml::xml_node<> *root_node = document.first_node ();
47+ rapidxml::xml_node<> *current_node = nullptr ;
48+
49+ if (strcmp (root_node->name (), " packages" ) != 0 ) {
50+ LOGE (" The root tag is not packages!" );
51+
52+ goto abort_xml_read;
53+ }
54+
55+ current_node = root_node->first_node (" package" );
56+ while (current_node) {
57+ {
58+ rapidxml::xml_attribute<> *name_attr = current_node->first_attribute (" name" );
59+ rapidxml::xml_attribute<> *code_path_attr = current_node->first_attribute (" codePath" );
60+
61+ if (!name_attr || !code_path_attr) goto continue_xml_loop;
62+
63+ char * code_path = code_path_attr->value ();
64+
65+ if (strlen (code_path) != dir_len) goto continue_xml_loop;
66+ if (strncmp (code_path, classpath_dir, dir_len) != 0 ) goto continue_xml_loop;
67+
68+ char * name = name_attr->value ();
69+ size_t name_len = strlen (name);
70+
71+ int copy_len = name_len < package_name_buffer_size - 1 ? static_cast <int >(name_len) : static_cast <int >(package_name_buffer_size - 1 );
72+ memcpy (package_name, name, copy_len * sizeof (char ));
73+ package_name[copy_len] = ' \0 ' ;
74+
75+ document.clear ();
76+ return true ;
77+ }
78+
79+ continue_xml_loop:
80+ current_node = current_node->next_sibling (" package" );
81+ }
82+
83+ abort_xml_read:
84+ document.clear ();
85+ return false ;
86+ }
87+
3488 if (decoder.parse () && decoder.root .get () && strcmp (decoder.root ->mTagName .data (), " packages" ) == 0 ) {
3589 for (auto pkg : decoder.root .get ()->subElements ) {
3690 if (strcmp (pkg.get ()->mTagName .data (), " package" ) != 0 ) continue ;
0 commit comments