Skip to content

Commit b130cd9

Browse files
committed
feat: add locate support for apk
1 parent 79c91a6 commit b130cd9

9 files changed

Lines changed: 65 additions & 31403 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ src/
44
package-lock.json
55
yarn.lock
66
yarn-error.log
7+
dist/

dist/app-info-parser.js

Lines changed: 0 additions & 31121 deletions
This file was deleted.

dist/app-info-parser.js.map

Lines changed: 0 additions & 259 deletions
This file was deleted.

dist/app-info-parser.min.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

dist/app-info-parser.min.js.map

Lines changed: 0 additions & 1 deletion
This file was deleted.

example/basic-use.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
<span style="width: 0; flex: 1; overflow-wrap: break-word; word-wrap: break-word;">${ result['versionName'] || result['CFBundleShortVersionString'] }</span>
5959
</p>
6060
</div>
61+
<pre>
62+
<code>${JSON.stringify(result, null, 2)}</code>
63+
</pre>
6164
`
6265
document.getElementById('result-list').appendChild(div)
6366
}).catch(e => {

lib/resource-finder.js

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function ResourceFinder() {
3939
* @param len length
4040
* @returns {Buffer}
4141
*/
42-
ResourceFinder.readBytes = function(bb, len) {
42+
ResourceFinder.readBytes = function (bb, len) {
4343
var uint8Array = new Uint8Array(len);
4444
for (var i = 0; i < len; i++) {
4545
uint8Array[i] = bb.readUint8();
@@ -54,7 +54,7 @@ ResourceFinder.readBytes = function(bb, len) {
5454
* @param {ByteBuffer} bb
5555
* @return {Map<String, Set<String>>}
5656
*/
57-
ResourceFinder.prototype.processResourceTable = function(resourceBuffer) {
57+
ResourceFinder.prototype.processResourceTable = function (resourceBuffer) {
5858
const bb = ByteBuffer.wrap(resourceBuffer, "binary", true);
5959

6060
// Resource table structure
@@ -139,7 +139,7 @@ ResourceFinder.prototype.processResourceTable = function(resourceBuffer) {
139139
*
140140
* @param {ByteBuffer} bb
141141
*/
142-
ResourceFinder.prototype.processPackage = function(bb) {
142+
ResourceFinder.prototype.processPackage = function (bb) {
143143
// Package structure
144144
var type = bb.readShort(),
145145
headerSize = bb.readShort(),
@@ -233,11 +233,42 @@ ResourceFinder.prototype.processPackage = function(bb) {
233233
}
234234
};
235235

236+
ResourceFinder.prototype.processConfig = function (bb) {
237+
var config_mcc = bb.readShort(),
238+
config_mnc = bb.readShort(),
239+
config_language = [bb.readByte(), bb.readByte()],
240+
config_region = [bb.readByte(), bb.readByte()]
241+
242+
var config = {
243+
language: '',
244+
region: '',
245+
locate: 'default'
246+
}
247+
248+
if (config_language.every(Boolean)) {
249+
config.language = config_language.map(byte => String.fromCharCode(byte)).join('')
250+
}
251+
252+
if (config_region.every(Boolean)) {
253+
config.region = config_region.map(byte => String.fromCharCode(byte)).join('')
254+
}
255+
256+
if (config.language) {
257+
config.locate = config.language
258+
}
259+
260+
if (config.region) {
261+
config.locate += `-r${config.region}`
262+
}
263+
264+
return config
265+
}
266+
236267
/**
237268
*
238269
* @param {ByteBuffer} bb
239270
*/
240-
ResourceFinder.prototype.processType = function(bb) {
271+
ResourceFinder.prototype.processType = function (bb) {
241272
var type = bb.readShort(),
242273
headerSize = bb.readShort(),
243274
size = bb.readInt(),
@@ -250,6 +281,9 @@ ResourceFinder.prototype.processType = function(bb) {
250281
var refKeys = {};
251282

252283
var config_size = bb.readInt();
284+
var configBuffer = ResourceFinder.readBytes(bb, config_size)
285+
286+
var res_config = this.processConfig(configBuffer)
253287

254288
// Skip the config data
255289
bb.offset = headerSize;
@@ -334,7 +368,7 @@ ResourceFinder.prototype.processType = function(bb) {
334368
}
335369
}
336370

337-
this.putIntoMap("@" + idStr, data);
371+
this.putIntoMap("@" + idStr, data, res_config);
338372
} else {
339373
// Complex case
340374
var entry_parent = bb.readInt();
@@ -351,10 +385,10 @@ ResourceFinder.prototype.processType = function(bb) {
351385
if (DEBUG) {
352386
console.log(
353387
"Entry 0x" +
354-
Number(resource_id).toString(16) +
355-
", key: " +
356-
this.keyStringPool[entry_key] +
357-
", complex value, not printed."
388+
Number(resource_id).toString(16) +
389+
", key: " +
390+
this.keyStringPool[entry_key] +
391+
", complex value, not printed."
358392
);
359393
}
360394
}
@@ -363,13 +397,13 @@ ResourceFinder.prototype.processType = function(bb) {
363397
for (var refK in refKeys) {
364398
var values = this.responseMap[
365399
"@" +
366-
Number(refKeys[refK])
367-
.toString(16)
368-
.toUpperCase()
400+
Number(refKeys[refK])
401+
.toString(16)
402+
.toUpperCase()
369403
];
370404
if (values != null && Object.keys(values).length < 1000) {
371405
for (var value in values) {
372-
this.putIntoMap("@" + refK, value);
406+
this.putIntoMap("@" + refK, value, res_config);
373407
}
374408
}
375409
}
@@ -380,7 +414,7 @@ ResourceFinder.prototype.processType = function(bb) {
380414
* @param {ByteBuffer} bb
381415
* @return {Array}
382416
*/
383-
ResourceFinder.prototype.processStringPool = function(bb) {
417+
ResourceFinder.prototype.processStringPool = function (bb) {
384418
// String pool structure
385419
//
386420
var type = bb.readShort(),
@@ -467,7 +501,7 @@ ResourceFinder.prototype.processStringPool = function(bb) {
467501
*
468502
* @param {ByteBuffer} bb
469503
*/
470-
ResourceFinder.prototype.processTypeSpec = function(bb) {
504+
ResourceFinder.prototype.processTypeSpec = function (bb) {
471505
var type = bb.readShort(),
472506
headerSize = bb.readShort(),
473507
size = bb.readInt(),
@@ -487,11 +521,14 @@ ResourceFinder.prototype.processTypeSpec = function(bb) {
487521
}
488522
};
489523

490-
ResourceFinder.prototype.putIntoMap = function(resId, value) {
524+
ResourceFinder.prototype.putIntoMap = function (resId, value, config) {
491525
if (this.responseMap[resId.toUpperCase()] == null) {
492526
this.responseMap[resId.toUpperCase()] = []
493527
}
494-
this.responseMap[resId.toUpperCase()].push(value)
528+
this.responseMap[resId.toUpperCase()].push({
529+
value,
530+
locate: config.locate
531+
})
495532
};
496533

497534
module.exports = ResourceFinder;

lib/utils.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ function findApkIconPath (info) {
9090
const maxDpiIcon = { dpi: 120, icon: '' }
9191

9292
for (const i in rulesMap) {
93-
info.application.icon.some((icon) => {
93+
info.application.icon.some(({ value: icon }) => {
9494
if (icon && icon.indexOf(i) !== -1) {
9595
resultMap['application-icon-' + rulesMap[i]] = icon
9696
return true
@@ -109,7 +109,8 @@ function findApkIconPath (info) {
109109

110110
if (Object.keys(resultMap).length === 0 || !maxDpiIcon.icon) {
111111
maxDpiIcon.dpi = 120
112-
maxDpiIcon.icon = info.application.icon[0] || ''
112+
const [{ value = '' }] = info.application.icon || [{}]
113+
maxDpiIcon.icon = value
113114
resultMap['applicataion-icon-120'] = maxDpiIcon.icon
114115
}
115116
return maxDpiIcon.icon

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
"name": "app-info-parser",
33
"version": "1.0.0",
44
"description": "Exact info from apk or ipa file.",
5-
"main": "./src/index.js",
5+
"main": "dist/app-info-parser.js",
6+
"files": [
7+
"dist"
8+
],
69
"scripts": {
710
"test": "node ./example/node.js",
811
"build": "rimraf src/* && babel lib -d src",

0 commit comments

Comments
 (0)