Example #1
0
static const struct zip_cd *find_cd_for_entry(const uint8_t *map, size_t size,
					      const struct zip_eocd *eocd,
					      const char *filename)
{
	/*
	 * eocd->cd_offset points to the beginning of eocd->entry_count number
	 * of Central Directories, one per entry. Find the one representing the
	 * requested filename.
	 */
	const struct zip_cd *cd;
	size_t i;

	die_if(eocd->cd_offset > size, "eocd offset too large");
	cd = (struct zip_cd *)(map + dtohl(eocd->cd_offset));
	for (i = 0; i < eocd->entry_count; i++) {
		uint16_t len;

		die_if(dtohl(cd->magic) != ZIP_CD_MAGIC,
		       "bad zip cd magic 0x%08x", dtohl(cd->magic));

		len = dtohs(cd->filename_length);
		if (len == strlen(filename) &&
		    !memcmp(cd->filename, filename, len))
			return cd;
		cd = (const struct zip_cd *)
			((const uint8_t *)cd + sizeof(*cd) + len +
			 dtohs(cd->extra_length) + dtohs(cd->comment_length));
		die_if((const uint8_t *)cd > map + size, "cd outside map");
	}
	die("no entry '%s' found", filename);
	return NULL;
}
Example #2
0
static void dump_type(const struct arsc_type *type)
{
	char c[CONFIG_LEN];

	config_to_string(&type->data.config, c);
	printf("type: id=0x%02x entry_count=%d entries_start=0x%02x config=%s\n",
	       dtohs(type->data.id), dtohl(type->data.entry_count),
	       dtohl(type->data.entries_start), c);
}
Example #3
0
static const struct zip_eocd *find_eocd(const uint8_t *map, size_t size)
{
	const struct zip_eocd *eocd;

	eocd = (struct zip_eocd *)(map + size - sizeof(*eocd));
	die_if(dtohl(eocd->magic) != ZIP_EOCD_MAGIC,
	       "bad zip eocd magic 0x%08x", dtohl(eocd->magic));
	die_if(dtohs(eocd->entry_count) == 0, "bad entry count 0");

	return eocd;
}
const ResTable_entry* TypeVariant::iterator::operator*() const {
    const ResTable_type* type = mTypeVariant->data;
    if (mIndex >= mTypeVariant->mLength) {
        return NULL;
    }

    const uint32_t entryCount = dtohl(mTypeVariant->data->entryCount);
    const uintptr_t containerEnd = reinterpret_cast<uintptr_t>(type)
            + dtohl(type->header.size);
    const uint32_t* const entryIndices = reinterpret_cast<const uint32_t*>(
            reinterpret_cast<uintptr_t>(type) + dtohs(type->header.headerSize));
    if (reinterpret_cast<uintptr_t>(entryIndices) + (sizeof(uint32_t) * entryCount) > containerEnd) {
        ALOGE("Type's entry indices extend beyond its boundaries");
        return NULL;
    }

    uint32_t entryOffset;
    if (type->flags & ResTable_type::FLAG_SPARSE) {
      auto iter = std::lower_bound(entryIndices, entryIndices + entryCount, mIndex, keyCompare);
      if (iter == entryIndices + entryCount
              || dtohs(ResTable_sparseTypeEntry{*iter}.idx) != mIndex) {
        return NULL;
      }

      entryOffset = static_cast<uint32_t>(dtohs(ResTable_sparseTypeEntry{*iter}.offset)) * 4u;
    } else {
      entryOffset = dtohl(entryIndices[mIndex]);
    }

    if (entryOffset == ResTable_type::NO_ENTRY) {
        return NULL;
    }

    if ((entryOffset & 0x3) != 0) {
        ALOGE("Index %u points to entry with unaligned offset 0x%08x", mIndex, entryOffset);
        return NULL;
    }

    const ResTable_entry* entry = reinterpret_cast<const ResTable_entry*>(
            reinterpret_cast<uintptr_t>(type) + dtohl(type->entriesStart) + entryOffset);
    if (reinterpret_cast<uintptr_t>(entry) > containerEnd - sizeof(*entry)) {
        ALOGE("Entry offset at index %u points outside the Type's boundaries", mIndex);
        return NULL;
    } else if (reinterpret_cast<uintptr_t>(entry) + dtohs(entry->size) > containerEnd) {
        ALOGE("Entry at index %u extends beyond Type's boundaries", mIndex);
        return NULL;
    } else if (dtohs(entry->size) < sizeof(*entry)) {
        ALOGE("Entry at index %u is too small (%u)", mIndex, dtohs(entry->size));
        return NULL;
    }
    return entry;
}
TypeVariant::TypeVariant(const ResTable_type* data) : data(data), mLength(dtohl(data->entryCount)) {
    if (data->flags & ResTable_type::FLAG_SPARSE) {
        const uint32_t entryCount = dtohl(data->entryCount);
        const uintptr_t containerEnd = reinterpret_cast<uintptr_t>(data) + dtohl(data->header.size);
        const uint32_t* const entryIndices = reinterpret_cast<const uint32_t*>(
                reinterpret_cast<uintptr_t>(data) + dtohs(data->header.headerSize));
        if (reinterpret_cast<uintptr_t>(entryIndices) + (sizeof(uint32_t) * entryCount)
                > containerEnd) {
            ALOGE("Type's entry indices extend beyond its boundaries");
            mLength = 0;
        } else {
          mLength = ResTable_sparseTypeEntry{entryIndices[entryCount - 1]}.idx + 1;
        }
    }
}
Example #6
0
static void dump(const struct blob *blob)
{
	uint32_t i;

	printf("header: package_count=%d\n",
	       dtohl(blob->header->data.package_count));
	printf("string pool (resource values): string_count=%d\n",
	       dtohl(blob->sp_values->data.string_count));
	for (i = 0; i < dtohl(blob->header->data.package_count); i++) {
		const struct package *pkg = &blob->packages[i];
		size_t j;

		printf("package: id=0x%02x spec_count=%zd\n",
		       dtohl(pkg->package->data.id), pkg->spec_count);
		printf("string pool (type names): string_count=%d\n",
		       dtohl(pkg->sp_type_names->data.string_count));
		printf("string pool (resource names): string_count=%d\n",
		       dtohl(pkg->sp_resource_names->data.string_count));
		for (j = 0; j < pkg->spec_count; j++) {
			const struct type_spec *spec = &pkg->specs[j];
			size_t k;

			printf("type spec: id=0x%02x type_count=%zd\n",
			       dtohs(spec->spec->data.id), spec->type_count);
			for (k = 0; k < spec->type_count; k++) {
				const struct arsc_type *type = spec->types[k];
				dump_type(type);
			}
		}
	}
}
Example #7
0
void map_file(const char *path, struct mapped_file *map)
{
	uint32_t magic;

	map_file0(path, map);
	magic = *(const uint32_t *)map->data;
	if (map->data_size > sizeof(uint32_t) &&
	    dtohl(magic) == ZIP_LFH_MAGIC) {
		/* file is likely an apk, modify map->data to point to the
		 * resources.arsc entry withinh the zip */
		adjust_map_to_zip_entry(map, "resources.arsc");
	}
}
TEST(ResStringPool, AppendToEmptyTable) {
  const size_t header_size = sizeof(android::ResStringPool_header);
  android::ResStringPool_header header = {
      {htods(android::RES_STRING_POOL_TYPE),
       htods(header_size),
       htodl(header_size)},
      0,
      0,
      htodl(android::ResStringPool_header::UTF8_FLAG |
            android::ResStringPool_header::SORTED_FLAG),
      0,
      0};
  android::ResStringPool pool((void*)&header, header_size, false);

  pool.appendString(android::String8("Hello, world"));
  auto big_string = make_big_string(300);
  auto big_chars = big_string.c_str();
  pool.appendString(android::String8(big_chars));
  pool.appendString(android::String8("€666"));
  pool.appendString(android::String8("banana banana"));
  android::Vector<char> v;
  pool.serialize(v);

  auto data = (void*)v.array();
  android::ResStringPool after(data, v.size(), false);

  // Ensure sort bit was cleared.
  auto flags = dtohl(((android::ResStringPool_header*)data)->flags);
  ASSERT_FALSE(flags & android::ResStringPool_header::SORTED_FLAG);

  size_t out_len;
  ASSERT_STREQ(after.string8At(0, &out_len), "Hello, world");
  ASSERT_EQ(out_len, 12);
  ASSERT_STREQ(after.string8At(1, &out_len), big_chars);
  ASSERT_EQ(out_len, 300);
  ASSERT_STREQ(after.string8At(2, &out_len), "€666");
  ASSERT_STREQ(after.string8At(3, &out_len), "banana banana");
}
Example #9
0
static void android_content_res_XResources_rewriteXmlReferencesNative(JNIEnv* env, jclass clazz,
            jint parserPtr, jobject origRes, jobject repRes) {

    ResXMLParser* parser = (ResXMLParser*)parserPtr;
    const ResXMLTree& mTree = parser->mTree;
    uint32_t* mResIds = (uint32_t*)mTree.mResIds;
    ResXMLTree_attrExt* tag;
    int attrCount;
    
    if (parser == NULL)
        return;
    
    do {
        switch (parser->next()) {
            case ResXMLParser::START_TAG:
                tag = (ResXMLTree_attrExt*)parser->mCurExt;
                attrCount = dtohs(tag->attributeCount);
                for (int idx = 0; idx < attrCount; idx++) {
                    ResXMLTree_attribute* attr = (ResXMLTree_attribute*)
                        (((const uint8_t*)tag)
                         + dtohs(tag->attributeStart)
                         + (dtohs(tag->attributeSize)*idx));
                         
                    // find resource IDs for attribute names
                    int32_t attrNameID = parser->getAttributeNameID(idx);
                    // only replace attribute name IDs for app packages
                    if (attrNameID >= 0 && (size_t)attrNameID < mTree.mNumResIds && dtohl(mResIds[attrNameID]) >= 0x7f000000) {
                        size_t attNameLen;
                        const char16_t* attrName = mTree.mStrings.stringAt(attrNameID, &attNameLen);
                        jint attrResID = env->CallStaticIntMethod(xresourcesClass, xresourcesTranslateAttrId,
                            env->NewString((const jchar*)attrName, attNameLen), origRes);
                        if (env->ExceptionCheck())
                            goto leave;
                            
                        mResIds[attrNameID] = htodl(attrResID);
                    }
                    
                    // find original resource IDs for reference values (app packages only)
                    if (attr->typedValue.dataType != Res_value::TYPE_REFERENCE)
                        continue;

                    jint oldValue = dtohl(attr->typedValue.data);
                    if (oldValue < 0x7f000000)
                        continue;
                    
                    jint newValue = env->CallStaticIntMethod(xresourcesClass, xresourcesTranslateResId,
                        oldValue, origRes, repRes);
                    if (env->ExceptionCheck())
                        goto leave;

                    if (newValue != oldValue)
                        attr->typedValue.data = htodl(newValue);
                }
                continue;
            case ResXMLParser::END_DOCUMENT:
            case ResXMLParser::BAD_DOCUMENT:
                goto leave;
            default:
                continue;
        }
    } while (true);
    
    leave:
    parser->restart();
}
Example #10
0
_mfs_error MFS_Find_next_slave
    (
    MFS_DRIVE_STRUCT_PTR  drive_ptr,    /*[IN] drive context */
    pointer   search_next_ptr           /*[IN] address of search data block indicating the current criteria and the results 
                                        ** of the last search results of this search are placed in this data block */
    )
{
    MFS_SEARCH_DATA_PTR        transfer_ptr;
    MFS_INTERNAL_SEARCH_PTR    internal_search_ptr;
    MFS_DIR_ENTRY_PTR          dir_entry_ptr;
    _mfs_error                 error_code;
    uint_32                    len;
    boolean                    found;
    boolean                    match_all;
    boolean                    eightdotthree = FALSE;
    char_ptr                   lfn;
    char                       sname[SFILENAME_SIZE+1]; 
    uint_32                    dotfile = 0;
    MFS_DIR_ENTRY  saved_dir_entry;  

    transfer_ptr = (MFS_SEARCH_DATA_PTR) search_next_ptr;
    error_code = MFS_NO_ERROR;
    found = FALSE;

    if ( transfer_ptr )
    {
        internal_search_ptr = &transfer_ptr->INTERNAL_SEARCH_DATA;

        if ( MFS_alloc_path(&lfn)!= MFS_NO_ERROR )
        {
            return MFS_INSUFFICIENT_MEMORY;
        }

        match_all = MFS_Check_search_string_for_all(internal_search_ptr->SRC_PTR);
        if ( !match_all )
        {
            dotfile = MFS_Is_dot_directory(internal_search_ptr->SRC_PTR);
            if ( dotfile == 0 )
            {
                eightdotthree = MFS_Check_search_string_for_8dot3( internal_search_ptr->SRC_PTR);
            }
        }
        do
        {
            dir_entry_ptr = MFS_Find_directory_entry(drive_ptr, NULL, &internal_search_ptr->CURRENT_CLUSTER, &internal_search_ptr->DIR_ENTRY_INDEX,
                &internal_search_ptr->PREV_CLUSTER, internal_search_ptr->ATTRIBUTE & (~ATTR_EXCLUSIVE), &error_code);

            if ( dir_entry_ptr == NULL && !error_code )
            {
                error_code = MFS_FILE_NOT_FOUND;
                break;
            }

            if ( internal_search_ptr->CURRENT_CLUSTER == CLUSTER_INVALID )
            {
                error_code = MFS_FILE_NOT_FOUND;
                break;
            }

            if ( dir_entry_ptr == NULL )
            {
                break;
            }
            saved_dir_entry=*dir_entry_ptr; 

            /* Make sure the entry is not an LFN entry */
            if ( *dir_entry_ptr->ATTRIBUTE != MFS_ATTR_LFN )
            {
                MFS_Compress_nondotfile (dir_entry_ptr->NAME, sname);

                if ( match_all )
                {
                    found = TRUE;
                }
                else
                {
                    if ( dotfile != 0 )
                    {
                        if ( dotfile == 1 )
                        {
                            found = internal_search_ptr->FULLNAME[0] == dir_entry_ptr->NAME[0];
                        }
                        else if ( dotfile == 2 )
                        {
                            found = (internal_search_ptr->FULLNAME[0] == dir_entry_ptr->NAME[0]) &&
                                    (internal_search_ptr->FULLNAME[1] == dir_entry_ptr->NAME[1]);
                        }
                        else
                        {
                            found = FALSE; /* This shouldn't happen */
                        }
                    }
                    else if ( eightdotthree )
                    {
                        found = MFS_Wildcard_match(internal_search_ptr->FILENAME, dir_entry_ptr->NAME);
                    }
                    else
                    {
                        if ( MFS_get_lfn_dir_cluster(drive_ptr, search_next_ptr, sname, lfn) == MFS_NO_ERROR )
                        {
                            found = MFS_lfn_match(internal_search_ptr->SRC_PTR, lfn, 0);
                        }
                        else
                        {
                            found = MFS_lfn_match(internal_search_ptr->SRC_PTR, sname, 0);
                        }  
                    }  
                }  
            }

            if ( !error_code )
            {
                error_code = MFS_Increment_dir_index(drive_ptr, &internal_search_ptr->CURRENT_CLUSTER,
                    &internal_search_ptr->DIR_ENTRY_INDEX, &internal_search_ptr->PREV_CLUSTER);  
            }

        } while ( (error_code == MFS_NO_ERROR) && (found  == FALSE) );

        if ( error_code == MFS_NO_ERROR )
        {
            transfer_ptr->ATTRIBUTE = dtohc(saved_dir_entry.ATTRIBUTE);
            transfer_ptr->TIME      = dtohs(saved_dir_entry.TIME);
            transfer_ptr->DATE      = dtohs(saved_dir_entry.DATE);
            transfer_ptr->FILE_SIZE = dtohl(saved_dir_entry.FILE_SIZE);

            /* Transfer the filename */
            len = _strnlen(sname,13);
            if ( sname[len-1] == '.' )
            {
                sname[len-1] = '\0';
            }
            strncpy(transfer_ptr->NAME, sname, 13);
        }

        MFS_free_path((pointer)lfn);
    }
    else
    {
        error_code = MFS_INVALID_MEMORY_BLOCK_ADDRESS;
    }  

    return(error_code);
}