appium-ios-remotexpc 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/build/src/base-plist-service.d.ts +51 -0
- package/build/src/base-plist-service.d.ts.map +1 -0
- package/build/src/base-plist-service.js +61 -0
- package/build/src/base-socket-service.d.ts +15 -0
- package/build/src/base-socket-service.d.ts.map +1 -0
- package/build/src/base-socket-service.js +46 -0
- package/build/src/index.d.ts +9 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +7 -0
- package/build/src/lib/apple-tv/constants.d.ts +77 -0
- package/build/src/lib/apple-tv/constants.d.ts.map +1 -0
- package/build/src/lib/apple-tv/constants.js +106 -0
- package/build/src/lib/apple-tv/encryption/chacha20-poly1305.d.ts +22 -0
- package/build/src/lib/apple-tv/encryption/chacha20-poly1305.d.ts.map +1 -0
- package/build/src/lib/apple-tv/encryption/chacha20-poly1305.js +97 -0
- package/build/src/lib/apple-tv/encryption/ed25519.d.ts +16 -0
- package/build/src/lib/apple-tv/encryption/ed25519.d.ts.map +1 -0
- package/build/src/lib/apple-tv/encryption/ed25519.js +93 -0
- package/build/src/lib/apple-tv/encryption/hkdf.d.ts +18 -0
- package/build/src/lib/apple-tv/encryption/hkdf.d.ts.map +1 -0
- package/build/src/lib/apple-tv/encryption/hkdf.js +73 -0
- package/build/src/lib/apple-tv/encryption/index.d.ts +5 -0
- package/build/src/lib/apple-tv/encryption/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/encryption/index.js +4 -0
- package/build/src/lib/apple-tv/encryption/opack2.d.ts +57 -0
- package/build/src/lib/apple-tv/encryption/opack2.d.ts.map +1 -0
- package/build/src/lib/apple-tv/encryption/opack2.js +203 -0
- package/build/src/lib/apple-tv/errors.d.ts +17 -0
- package/build/src/lib/apple-tv/errors.d.ts.map +1 -0
- package/build/src/lib/apple-tv/errors.js +30 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts +19 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/decoder.js +49 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts +10 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/encoder.js +20 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts +4 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/index.js +3 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts +14 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.js +27 -0
- package/build/src/lib/apple-tv/types.d.ts +36 -0
- package/build/src/lib/apple-tv/types.d.ts.map +1 -0
- package/build/src/lib/apple-tv/types.js +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts +40 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.js +76 -0
- package/build/src/lib/apple-tv/utils/index.d.ts +3 -0
- package/build/src/lib/apple-tv/utils/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/index.js +2 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts +9 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.js +36 -0
- package/build/src/lib/lockdown/index.d.ts +87 -0
- package/build/src/lib/lockdown/index.d.ts.map +1 -0
- package/build/src/lib/lockdown/index.js +324 -0
- package/build/src/lib/pair-record/index.d.ts +3 -0
- package/build/src/lib/pair-record/index.d.ts.map +1 -0
- package/build/src/lib/pair-record/index.js +2 -0
- package/build/src/lib/pair-record/pair-record.d.ts +48 -0
- package/build/src/lib/pair-record/pair-record.d.ts.map +1 -0
- package/build/src/lib/pair-record/pair-record.js +85 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-creator.js +475 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-parser.js +449 -0
- package/build/src/lib/plist/constants.d.ts +36 -0
- package/build/src/lib/plist/constants.d.ts.map +1 -0
- package/build/src/lib/plist/constants.js +43 -0
- package/build/src/lib/plist/index.d.ts +14 -0
- package/build/src/lib/plist/index.d.ts.map +1 -0
- package/build/src/lib/plist/index.js +16 -0
- package/build/src/lib/plist/length-based-splitter.d.ts +43 -0
- package/build/src/lib/plist/length-based-splitter.d.ts.map +1 -0
- package/build/src/lib/plist/length-based-splitter.js +228 -0
- package/build/src/lib/plist/plist-creator.d.ts +8 -0
- package/build/src/lib/plist/plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/plist-creator.js +33 -0
- package/build/src/lib/plist/plist-decoder.d.ts +25 -0
- package/build/src/lib/plist/plist-decoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-decoder.js +103 -0
- package/build/src/lib/plist/plist-encoder.d.ts +10 -0
- package/build/src/lib/plist/plist-encoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-encoder.js +27 -0
- package/build/src/lib/plist/plist-parser.d.ts +9 -0
- package/build/src/lib/plist/plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/plist-parser.js +109 -0
- package/build/src/lib/plist/plist-service.d.ts +86 -0
- package/build/src/lib/plist/plist-service.d.ts.map +1 -0
- package/build/src/lib/plist/plist-service.js +180 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts +9 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-creator.js +14 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts +8 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-parser.js +23 -0
- package/build/src/lib/plist/utils.d.ts +97 -0
- package/build/src/lib/plist/utils.d.ts.map +1 -0
- package/build/src/lib/plist/utils.js +287 -0
- package/build/src/lib/remote-xpc/constants.d.ts +20 -0
- package/build/src/lib/remote-xpc/constants.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/constants.js +21 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts +74 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake-frames.js +285 -0
- package/build/src/lib/remote-xpc/handshake.d.ts +14 -0
- package/build/src/lib/remote-xpc/handshake.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake.js +95 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts +55 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.js +365 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts +22 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/xpc-protocol.js +368 -0
- package/build/src/lib/tunnel/index.d.ts +69 -0
- package/build/src/lib/tunnel/index.d.ts.map +1 -0
- package/build/src/lib/tunnel/index.js +205 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts +46 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-client.js +152 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts +37 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-server.js +109 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts +85 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-api-client.js +207 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts +68 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-registry-server.js +351 -0
- package/build/src/lib/types.d.ts +238 -0
- package/build/src/lib/types.d.ts.map +1 -0
- package/build/src/lib/types.js +4 -0
- package/build/src/lib/usbmux/index.d.ts +177 -0
- package/build/src/lib/usbmux/index.d.ts.map +1 -0
- package/build/src/lib/usbmux/index.js +490 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts +19 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-decoder.js +38 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts +12 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-encoder.js +32 -0
- package/build/src/service-connection.d.ts +34 -0
- package/build/src/service-connection.d.ts.map +1 -0
- package/build/src/service-connection.js +51 -0
- package/build/src/services/index.d.ts +6 -0
- package/build/src/services/index.d.ts.map +1 -0
- package/build/src/services/index.js +5 -0
- package/build/src/services/ios/base-service.d.ts +35 -0
- package/build/src/services/ios/base-service.d.ts.map +1 -0
- package/build/src/services/ios/base-service.js +55 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts +46 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/index.js +169 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts +5 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/keys.js +770 -0
- package/build/src/services/ios/syslog-service/index.d.ts +91 -0
- package/build/src/services/ios/syslog-service/index.d.ts.map +1 -0
- package/build/src/services/ios/syslog-service/index.js +323 -0
- package/build/src/services/ios/tunnel-service/index.d.ts +17 -0
- package/build/src/services/ios/tunnel-service/index.d.ts.map +1 -0
- package/build/src/services/ios/tunnel-service/index.js +57 -0
- package/build/src/services.d.ts +14 -0
- package/build/src/services.d.ts.map +1 -0
- package/build/src/services.js +48 -0
- package/package.json +12 -3
- package/src/lib/apple-tv/constants.ts +42 -0
- package/src/lib/apple-tv/encryption/chacha20-poly1305.ts +147 -0
- package/src/lib/apple-tv/encryption/ed25519.ts +126 -0
- package/src/lib/apple-tv/encryption/hkdf.ts +95 -0
- package/src/lib/apple-tv/encryption/index.ts +11 -0
- package/src/lib/apple-tv/encryption/opack2.ts +257 -0
- package/.github/dependabot.yml +0 -38
- package/.github/workflows/format-check.yml +0 -43
- package/.github/workflows/lint-and-build.yml +0 -40
- package/.github/workflows/pr-title.yml +0 -16
- package/.github/workflows/publish.js.yml +0 -43
- package/.github/workflows/test-validation.yml +0 -40
- package/.mocharc.json +0 -8
- package/.prettierignore +0 -3
- package/.prettierrc +0 -17
- package/.releaserc +0 -48
- package/assets/images/ios-arch.png +0 -0
- package/eslint.config.js +0 -45
- package/npm-shrinkwrap.json +0 -2711
- package/test/integration/diagnostics-test.ts +0 -44
- package/test/integration/read-pair-record-test.ts +0 -39
- package/test/integration/tunnel-test.ts +0 -104
- package/test/unit/apple-tv/tlv/decoder.spec.ts +0 -144
- package/test/unit/apple-tv/tlv/encoder.spec.ts +0 -91
- package/test/unit/apple-tv/tlv/pairing-tlv.spec.ts +0 -101
- package/test/unit/apple-tv/tlv/tlv-integration.spec.ts +0 -146
- package/test/unit/apple-tv/utils/buffer-utils.spec.ts +0 -74
- package/test/unit/apple-tv/utils/uuid-generator.spec.ts +0 -39
- package/test/unit/fixtures/index.ts +0 -88
- package/test/unit/fixtures/usbmuxconnectmessage.bin +0 -0
- package/test/unit/fixtures/usbmuxlistdevicemessage.bin +0 -0
- package/test/unit/plist/error-handling.spec.ts +0 -101
- package/test/unit/plist/fixtures/sample.binary.plist +0 -0
- package/test/unit/plist/fixtures/sample.xml.plist +0 -38
- package/test/unit/plist/plist-parser.spec.ts +0 -283
- package/test/unit/plist/plist.spec.ts +0 -205
- package/test/unit/plist/tag-position-handling.spec.ts +0 -90
- package/test/unit/plist/unified-plist-parser.spec.ts +0 -227
- package/test/unit/plist/utils.spec.ts +0 -249
- package/test/unit/plist/xml-cleaning.spec.ts +0 -60
- package/test/unit/tunnel/tunnel-registry-server.spec.ts +0 -194
- package/test/unit/usbmux/usbmux-specs.ts +0 -71
- package/tsconfig.json +0 -36
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary Property List (bplist) Parser
|
|
3
|
+
*
|
|
4
|
+
* This module provides functionality to parse binary property lists (bplists)
|
|
5
|
+
* commonly used in Apple's iOS and macOS systems.
|
|
6
|
+
*/
|
|
7
|
+
import { logger } from '@appium/support';
|
|
8
|
+
import { APPLE_EPOCH_OFFSET, BPLIST_MAGIC_AND_VERSION, BPLIST_TRAILER_SIZE, BPLIST_TYPE, } from './constants.js';
|
|
9
|
+
const log = logger.getLogger('Plist');
|
|
10
|
+
/**
|
|
11
|
+
* Class for parsing binary property lists
|
|
12
|
+
*/
|
|
13
|
+
class BinaryPlistParser {
|
|
14
|
+
_buffer;
|
|
15
|
+
_offsetSize;
|
|
16
|
+
_objectRefSize;
|
|
17
|
+
_numObjects;
|
|
18
|
+
_topObject;
|
|
19
|
+
_offsetTableOffset;
|
|
20
|
+
_objectTable;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new BinaryPlistParser
|
|
23
|
+
* @param buffer - The binary plist data as a Buffer
|
|
24
|
+
*/
|
|
25
|
+
constructor(buffer) {
|
|
26
|
+
this._buffer = buffer;
|
|
27
|
+
this._objectTable = [];
|
|
28
|
+
// Initialize with default values, will be set in parseTrailer
|
|
29
|
+
this._offsetSize = 0;
|
|
30
|
+
this._objectRefSize = 0;
|
|
31
|
+
this._numObjects = 0;
|
|
32
|
+
this._topObject = 0;
|
|
33
|
+
this._offsetTableOffset = 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parses the binary plist
|
|
37
|
+
* @returns The parsed JavaScript object
|
|
38
|
+
*/
|
|
39
|
+
parse() {
|
|
40
|
+
this._validateHeader();
|
|
41
|
+
this._parseTrailer();
|
|
42
|
+
this._parseObjects();
|
|
43
|
+
this._resolveReferences();
|
|
44
|
+
return this._handleTopObject();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validates the binary plist header
|
|
48
|
+
* @throws Error if the buffer is not a valid binary plist
|
|
49
|
+
*/
|
|
50
|
+
_validateHeader() {
|
|
51
|
+
if (this._buffer.length < 8 ||
|
|
52
|
+
!this._buffer.slice(0, 8).equals(BPLIST_MAGIC_AND_VERSION)) {
|
|
53
|
+
throw new Error('Not a binary plist. Expected bplist00 magic.');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parses the trailer section of the binary plist
|
|
58
|
+
* @throws Error if the buffer is too small to contain a trailer
|
|
59
|
+
*/
|
|
60
|
+
_parseTrailer() {
|
|
61
|
+
if (this._buffer.length < BPLIST_TRAILER_SIZE) {
|
|
62
|
+
throw new Error('Binary plist is too small to contain a trailer.');
|
|
63
|
+
}
|
|
64
|
+
const trailer = this._buffer.slice(this._buffer.length - BPLIST_TRAILER_SIZE);
|
|
65
|
+
// Extract trailer information
|
|
66
|
+
this._offsetSize = trailer.readUInt8(6);
|
|
67
|
+
this._objectRefSize = trailer.readUInt8(7);
|
|
68
|
+
this._numObjects = Number(trailer.readBigUInt64BE(8));
|
|
69
|
+
this._topObject = Number(trailer.readBigUInt64BE(16));
|
|
70
|
+
this._offsetTableOffset = Number(trailer.readBigUInt64BE(24));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Reads an object reference from the buffer
|
|
74
|
+
* @param offset - The offset to read from
|
|
75
|
+
* @returns The object reference index
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* Helper method to read multi-byte integers safely, handling potential overflow
|
|
79
|
+
* @param startOffset - The offset to start reading from
|
|
80
|
+
* @param byteCount - The number of bytes to read
|
|
81
|
+
* @param valueName - Name of the value type for error messages
|
|
82
|
+
* @returns The parsed integer value
|
|
83
|
+
*/
|
|
84
|
+
_readMultiByteInteger(startOffset, byteCount, valueName) {
|
|
85
|
+
// Use BigInt for calculations if byteCount is large enough to potentially overflow
|
|
86
|
+
if (byteCount > 6) {
|
|
87
|
+
// 6 bytes = 48 bits, safely under MAX_SAFE_INTEGER
|
|
88
|
+
let result = 0n;
|
|
89
|
+
for (let i = 0; i < byteCount; i++) {
|
|
90
|
+
result =
|
|
91
|
+
(result << 8n) | BigInt(this._buffer.readUInt8(startOffset + i));
|
|
92
|
+
}
|
|
93
|
+
// Check if the value exceeds MAX_SAFE_INTEGER
|
|
94
|
+
if (result > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
95
|
+
throw new Error(`${valueName} value ${result} exceeds MAX_SAFE_INTEGER. Cannot safely convert to number.`);
|
|
96
|
+
}
|
|
97
|
+
// Safe to convert to number without precision loss
|
|
98
|
+
return Number(result);
|
|
99
|
+
}
|
|
100
|
+
// Use regular number arithmetic for smaller values
|
|
101
|
+
let result = 0;
|
|
102
|
+
for (let i = 0; i < byteCount; i++) {
|
|
103
|
+
result = (result << 8) | this._buffer.readUInt8(startOffset + i);
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
_readObjectRef(offset) {
|
|
108
|
+
return this._readMultiByteInteger(offset, this._objectRefSize, 'Object reference');
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Reads an offset from the offset table
|
|
112
|
+
* @param index - The index in the offset table
|
|
113
|
+
* @returns The offset value
|
|
114
|
+
*/
|
|
115
|
+
_readOffset(index) {
|
|
116
|
+
const offsetStart = this._offsetTableOffset + index * this._offsetSize;
|
|
117
|
+
return this._readMultiByteInteger(offsetStart, this._offsetSize, 'Offset');
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parses an integer value from the buffer
|
|
121
|
+
* @param startOffset - The offset to start reading from
|
|
122
|
+
* @param intByteCount - The number of bytes to read
|
|
123
|
+
* @returns The parsed integer value (number or bigint)
|
|
124
|
+
*/
|
|
125
|
+
_parseIntegerValue(startOffset, intByteCount) {
|
|
126
|
+
// Handle different integer sizes
|
|
127
|
+
switch (intByteCount) {
|
|
128
|
+
case 1:
|
|
129
|
+
return this._buffer.readInt8(startOffset);
|
|
130
|
+
case 2:
|
|
131
|
+
return this._buffer.readInt16BE(startOffset);
|
|
132
|
+
case 4:
|
|
133
|
+
return this._buffer.readInt32BE(startOffset);
|
|
134
|
+
case 8: {
|
|
135
|
+
// For 64-bit integers, we need to handle potential precision loss
|
|
136
|
+
const bigInt = this._buffer.readBigInt64BE(startOffset);
|
|
137
|
+
const intValue = Number(bigInt);
|
|
138
|
+
// Check if conversion to Number caused precision loss
|
|
139
|
+
if (BigInt(intValue) !== bigInt) {
|
|
140
|
+
log.warn('Precision loss when converting 64-bit integer to Number. Returning BigInt value.');
|
|
141
|
+
return bigInt; // Return the BigInt directly to avoid precision loss
|
|
142
|
+
}
|
|
143
|
+
return intValue; // Return as number if no precision loss
|
|
144
|
+
}
|
|
145
|
+
default:
|
|
146
|
+
throw new TypeError(`Unexpected integer byte count: ${intByteCount}. Cannot parse integer value.`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Parses a real (floating point) value from the buffer
|
|
151
|
+
* @param startOffset - The offset to start reading from
|
|
152
|
+
* @param floatByteCount - The number of bytes to read
|
|
153
|
+
* @returns The parsed floating point value
|
|
154
|
+
*/
|
|
155
|
+
_parseRealValue(startOffset, floatByteCount) {
|
|
156
|
+
switch (floatByteCount) {
|
|
157
|
+
case 4:
|
|
158
|
+
return this._buffer.readFloatBE(startOffset);
|
|
159
|
+
case 8:
|
|
160
|
+
return this._buffer.readDoubleBE(startOffset);
|
|
161
|
+
default:
|
|
162
|
+
throw new TypeError(`Unexpected float byte count: ${floatByteCount}. Cannot parse real value.`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Parses a date value from the buffer
|
|
167
|
+
* @param startOffset - The offset to start reading from
|
|
168
|
+
* @returns The parsed Date object
|
|
169
|
+
*/
|
|
170
|
+
_parseDateValue(startOffset) {
|
|
171
|
+
// Date is stored as a float, seconds since 2001-01-01
|
|
172
|
+
const timestamp = this._buffer.readDoubleBE(startOffset);
|
|
173
|
+
// Convert Apple epoch (2001-01-01) to Unix epoch (1970-01-01)
|
|
174
|
+
return new Date((timestamp + APPLE_EPOCH_OFFSET) * 1000);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Parses a data value from the buffer
|
|
178
|
+
* @param startOffset - The offset to start reading from
|
|
179
|
+
* @param objLength - The length of the data
|
|
180
|
+
* @returns The parsed Buffer
|
|
181
|
+
*/
|
|
182
|
+
_parseDataValue(startOffset, objLength) {
|
|
183
|
+
return Buffer.from(this._buffer.slice(startOffset, startOffset + objLength));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Parses an ASCII string from the buffer
|
|
187
|
+
* @param startOffset - The offset to start reading from
|
|
188
|
+
* @param objLength - The length of the string
|
|
189
|
+
* @returns The parsed string
|
|
190
|
+
*/
|
|
191
|
+
_parseAsciiString(startOffset, objLength) {
|
|
192
|
+
return this._buffer
|
|
193
|
+
.slice(startOffset, startOffset + objLength)
|
|
194
|
+
.toString('ascii');
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Parses a Unicode string from the buffer
|
|
198
|
+
* @param startOffset - The offset to start reading from
|
|
199
|
+
* @param objLength - The length of the string in characters
|
|
200
|
+
* @returns The parsed string
|
|
201
|
+
*/
|
|
202
|
+
_parseUnicodeString(startOffset, objLength) {
|
|
203
|
+
// Unicode strings are stored as UTF-16BE
|
|
204
|
+
const utf16Buffer = Buffer.alloc(objLength * 2);
|
|
205
|
+
for (let j = 0; j < objLength; j++) {
|
|
206
|
+
utf16Buffer.writeUInt16BE(this._buffer.readUInt16BE(startOffset + j * 2), j * 2);
|
|
207
|
+
}
|
|
208
|
+
return utf16Buffer.toString('utf16le', 0, objLength * 2);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Parses a UID value from the buffer
|
|
212
|
+
* @param startOffset - The offset to start reading from
|
|
213
|
+
* @param uidByteCount - The number of bytes to read
|
|
214
|
+
* @returns The parsed UID value
|
|
215
|
+
*/
|
|
216
|
+
_parseUidValue(startOffset, uidByteCount) {
|
|
217
|
+
return this._readMultiByteInteger(startOffset, uidByteCount, 'UID');
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Parses all objects in the binary plist
|
|
221
|
+
*/
|
|
222
|
+
_parseObjects() {
|
|
223
|
+
for (let i = 0; i < this._numObjects; i++) {
|
|
224
|
+
const objOffset = this._readOffset(i);
|
|
225
|
+
const objType = this._buffer.readUInt8(objOffset) & 0xf0;
|
|
226
|
+
const objInfo = this._buffer.readUInt8(objOffset) & 0x0f;
|
|
227
|
+
let objLength = objInfo;
|
|
228
|
+
let startOffset = objOffset + 1;
|
|
229
|
+
// For objects with length > 15, the actual length follows
|
|
230
|
+
if (objInfo === 0x0f) {
|
|
231
|
+
const intType = this._buffer.readUInt8(startOffset) & 0xf0;
|
|
232
|
+
if (intType !== BPLIST_TYPE.INT) {
|
|
233
|
+
throw new TypeError(`Expected integer type for length at offset ${startOffset}`);
|
|
234
|
+
}
|
|
235
|
+
const intInfo = this._buffer.readUInt8(startOffset) & 0x0f;
|
|
236
|
+
startOffset++;
|
|
237
|
+
// Read the length based on the integer size
|
|
238
|
+
const intByteCount = 1 << intInfo;
|
|
239
|
+
objLength = this._readMultiByteInteger(startOffset, intByteCount, 'Object length');
|
|
240
|
+
startOffset += intByteCount;
|
|
241
|
+
}
|
|
242
|
+
// Parse the object based on its type
|
|
243
|
+
this._objectTable[i] = this._parseObjectByType(objType, objInfo, startOffset, objLength);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Parses an object based on its type
|
|
248
|
+
* @param objType - The object type
|
|
249
|
+
* @param objInfo - The object info
|
|
250
|
+
* @param startOffset - The start offset
|
|
251
|
+
* @param objLength - The object length
|
|
252
|
+
* @returns The parsed object
|
|
253
|
+
*/
|
|
254
|
+
_parseObjectByType(objType, objInfo, startOffset, objLength) {
|
|
255
|
+
switch (objType) {
|
|
256
|
+
case BPLIST_TYPE.NULL:
|
|
257
|
+
return this._parseNullType(objInfo);
|
|
258
|
+
case BPLIST_TYPE.INT:
|
|
259
|
+
return this._parseIntegerValue(startOffset, 1 << objInfo);
|
|
260
|
+
case BPLIST_TYPE.REAL:
|
|
261
|
+
return this._parseRealValue(startOffset, 1 << objInfo);
|
|
262
|
+
case BPLIST_TYPE.DATE:
|
|
263
|
+
return this._parseDateValue(startOffset);
|
|
264
|
+
case BPLIST_TYPE.DATA:
|
|
265
|
+
return this._parseDataValue(startOffset, objLength);
|
|
266
|
+
case BPLIST_TYPE.STRING_ASCII:
|
|
267
|
+
return this._parseAsciiString(startOffset, objLength);
|
|
268
|
+
case BPLIST_TYPE.STRING_UNICODE:
|
|
269
|
+
return this._parseUnicodeString(startOffset, objLength);
|
|
270
|
+
case BPLIST_TYPE.UID:
|
|
271
|
+
return this._parseUidValue(startOffset, objInfo + 1);
|
|
272
|
+
case BPLIST_TYPE.ARRAY:
|
|
273
|
+
return this._createTempArray(objLength, startOffset);
|
|
274
|
+
case BPLIST_TYPE.DICT:
|
|
275
|
+
return this._createTempDict(objLength, startOffset);
|
|
276
|
+
default:
|
|
277
|
+
throw new TypeError(`Unsupported binary plist object type: ${objType.toString(16)}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Parses a null type object
|
|
282
|
+
* @param objInfo - The object info
|
|
283
|
+
* @returns The parsed value (null, false, or true)
|
|
284
|
+
*/
|
|
285
|
+
_parseNullType(objInfo) {
|
|
286
|
+
switch (objInfo) {
|
|
287
|
+
case 0x00:
|
|
288
|
+
return null;
|
|
289
|
+
case 0x08:
|
|
290
|
+
return false;
|
|
291
|
+
case 0x09:
|
|
292
|
+
return true;
|
|
293
|
+
case 0x0f:
|
|
294
|
+
return null; // fill byte
|
|
295
|
+
default:
|
|
296
|
+
throw new TypeError(`Unexpected null type object info: 0x${objInfo.toString(16)}. Cannot parse null value.`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Creates a temporary array object
|
|
301
|
+
* @param objLength - The array length
|
|
302
|
+
* @param startOffset - The start offset
|
|
303
|
+
* @returns The temporary array object
|
|
304
|
+
*/
|
|
305
|
+
_createTempArray(objLength, startOffset) {
|
|
306
|
+
return {
|
|
307
|
+
type: 'array',
|
|
308
|
+
objLength,
|
|
309
|
+
startOffset,
|
|
310
|
+
value: [],
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Creates a temporary dictionary object
|
|
315
|
+
* @param objLength - The dictionary length
|
|
316
|
+
* @param startOffset - The start offset
|
|
317
|
+
* @returns The temporary dictionary object
|
|
318
|
+
*/
|
|
319
|
+
_createTempDict(objLength, startOffset) {
|
|
320
|
+
return {
|
|
321
|
+
type: 'dict',
|
|
322
|
+
objLength,
|
|
323
|
+
startOffset,
|
|
324
|
+
value: {},
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Type guard to check if an object is a TempObject
|
|
329
|
+
* @param obj - The object to check
|
|
330
|
+
* @returns True if the object is a TempObject
|
|
331
|
+
*/
|
|
332
|
+
_isTempObject(obj) {
|
|
333
|
+
return typeof obj === 'object' && obj !== null && 'type' in obj;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Resolves references for arrays and dictionaries
|
|
337
|
+
*/
|
|
338
|
+
_resolveReferences() {
|
|
339
|
+
for (let i = 0; i < this._numObjects; i++) {
|
|
340
|
+
const obj = this._objectTable[i];
|
|
341
|
+
if (this._isTempObject(obj)) {
|
|
342
|
+
if (obj.type === 'array') {
|
|
343
|
+
this._resolveArrayReferences(obj, i);
|
|
344
|
+
}
|
|
345
|
+
else if (obj.type === 'dict') {
|
|
346
|
+
this._resolveDictReferences(obj, i);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Resolves references for an array
|
|
353
|
+
* @param obj - The temporary array object
|
|
354
|
+
* @param index - The index in the object table
|
|
355
|
+
*/
|
|
356
|
+
_resolveArrayReferences(obj, index) {
|
|
357
|
+
const array = obj.value;
|
|
358
|
+
for (let j = 0; j < obj.objLength; j++) {
|
|
359
|
+
const refIdx = this._readObjectRef(obj.startOffset + j * this._objectRefSize);
|
|
360
|
+
const refValue = this._objectTable[refIdx];
|
|
361
|
+
// Ensure we're not adding a TempObject to the array
|
|
362
|
+
if (!this._isTempObject(refValue)) {
|
|
363
|
+
array.push(refValue);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
this._objectTable[index] = array;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Resolves references for a dictionary
|
|
370
|
+
* @param obj - The temporary dictionary object
|
|
371
|
+
* @param index - The index in the object table
|
|
372
|
+
*/
|
|
373
|
+
_resolveDictReferences(obj, index) {
|
|
374
|
+
const dict = obj.value;
|
|
375
|
+
const keyCount = obj.objLength;
|
|
376
|
+
// Keys are stored first, followed by values
|
|
377
|
+
for (let j = 0; j < keyCount; j++) {
|
|
378
|
+
const keyRef = this._readObjectRef(obj.startOffset + j * this._objectRefSize);
|
|
379
|
+
const valueRef = this._readObjectRef(obj.startOffset + (keyCount + j) * this._objectRefSize);
|
|
380
|
+
const key = this._objectTable[keyRef];
|
|
381
|
+
const value = this._objectTable[valueRef];
|
|
382
|
+
if (typeof key !== 'string') {
|
|
383
|
+
throw new TypeError(`Dictionary key must be a string, got ${typeof key}`);
|
|
384
|
+
}
|
|
385
|
+
// Ensure we're not adding a TempObject to the dictionary
|
|
386
|
+
if (!this._isTempObject(value)) {
|
|
387
|
+
dict[key] = value;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
this._objectTable[index] = dict;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Handles special case for the top object
|
|
394
|
+
* @returns The final parsed value
|
|
395
|
+
*/
|
|
396
|
+
_handleTopObject() {
|
|
397
|
+
// If the top object is an empty object but we have key-value pairs in the array format,
|
|
398
|
+
// convert it to a proper object
|
|
399
|
+
if (this._topObject === 0 &&
|
|
400
|
+
this._objectTable[0] &&
|
|
401
|
+
typeof this._objectTable[0] === 'object' &&
|
|
402
|
+
!this._isTempObject(this._objectTable[0]) &&
|
|
403
|
+
Object.keys(this._objectTable[0]).length === 0 &&
|
|
404
|
+
this._objectTable.length > 1) {
|
|
405
|
+
return this._convertArrayToDict();
|
|
406
|
+
}
|
|
407
|
+
// Ensure the top object is a PlistValue and not a TempObject
|
|
408
|
+
const topValue = this._objectTable[this._topObject];
|
|
409
|
+
if (this._isTempObject(topValue)) {
|
|
410
|
+
return topValue.value;
|
|
411
|
+
}
|
|
412
|
+
return topValue;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Converts an array format to a dictionary
|
|
416
|
+
* @returns The converted dictionary
|
|
417
|
+
*/
|
|
418
|
+
_convertArrayToDict() {
|
|
419
|
+
const result = {};
|
|
420
|
+
// Process the array in key-value pairs
|
|
421
|
+
for (let i = 1; i < this._objectTable.length; i += 2) {
|
|
422
|
+
const key = this._objectTable[i];
|
|
423
|
+
if (i + 1 < this._objectTable.length && typeof key === 'string') {
|
|
424
|
+
const value = this._objectTable[i + 1];
|
|
425
|
+
if (!this._isTempObject(value)) {
|
|
426
|
+
result[key] = value;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return result;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Parses a binary plist buffer into a JavaScript object
|
|
435
|
+
* @param buffer - The binary plist data as a Buffer
|
|
436
|
+
* @returns The parsed JavaScript object
|
|
437
|
+
*/
|
|
438
|
+
export function parseBinaryPlist(buffer) {
|
|
439
|
+
const parser = new BinaryPlistParser(buffer);
|
|
440
|
+
return parser.parse();
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Determines if a buffer is a binary plist
|
|
444
|
+
* @param buffer - The buffer to check
|
|
445
|
+
* @returns True if the buffer is a binary plist
|
|
446
|
+
*/
|
|
447
|
+
export function isBinaryPlist(buffer) {
|
|
448
|
+
return (buffer.length >= 8 && buffer.slice(0, 8).equals(BPLIST_MAGIC_AND_VERSION));
|
|
449
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common constants for plist operations
|
|
3
|
+
*/
|
|
4
|
+
export declare const BPLIST_MAGIC = "bplist";
|
|
5
|
+
export declare const BPLIST_VERSION = "00";
|
|
6
|
+
export declare const BPLIST_MAGIC_AND_VERSION: Buffer<ArrayBuffer>;
|
|
7
|
+
export declare const BINARY_PLIST_MAGIC = "bplist00";
|
|
8
|
+
export declare const IBINARY_PLIST_MAGIC = "Ibplist00";
|
|
9
|
+
export declare const BINARY_PLIST_HEADER_LENGTH = 9;
|
|
10
|
+
export declare const XML_DECLARATION = "<?xml";
|
|
11
|
+
export declare const PLIST_CLOSING_TAG = "</plist>";
|
|
12
|
+
export declare const LENGTH_FIELD_1_BYTE = 1;
|
|
13
|
+
export declare const LENGTH_FIELD_2_BYTES = 2;
|
|
14
|
+
export declare const LENGTH_FIELD_4_BYTES = 4;
|
|
15
|
+
export declare const LENGTH_FIELD_8_BYTES = 8;
|
|
16
|
+
export declare const UINT32_HIGH_MULTIPLIER = 4294967296;
|
|
17
|
+
export declare const UTF8_ENCODING = "utf8";
|
|
18
|
+
export declare const APPLE_EPOCH_OFFSET = 978307200;
|
|
19
|
+
export declare const BPLIST_TRAILER_SIZE = 32;
|
|
20
|
+
export declare const BPLIST_TYPE: {
|
|
21
|
+
NULL: number;
|
|
22
|
+
FALSE: number;
|
|
23
|
+
TRUE: number;
|
|
24
|
+
FILL: number;
|
|
25
|
+
INT: number;
|
|
26
|
+
REAL: number;
|
|
27
|
+
DATE: number;
|
|
28
|
+
DATA: number;
|
|
29
|
+
STRING_ASCII: number;
|
|
30
|
+
STRING_UNICODE: number;
|
|
31
|
+
UID: number;
|
|
32
|
+
ARRAY: number;
|
|
33
|
+
SET: number;
|
|
34
|
+
DICT: number;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/lib/plist/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,cAAc,OAAO,CAAC;AACnC,eAAO,MAAM,wBAAwB,qBAEpC,CAAC;AAGF,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAC7C,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAC/C,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAG5C,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAG5C,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,sBAAsB,aAAc,CAAC;AAGlD,eAAO,MAAM,aAAa,SAAS,CAAC;AAGpC,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAG5C,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAGtC,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;CAevB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common constants for plist operations
|
|
3
|
+
*/
|
|
4
|
+
// Constants for binary plist format
|
|
5
|
+
export const BPLIST_MAGIC = 'bplist';
|
|
6
|
+
export const BPLIST_VERSION = '00';
|
|
7
|
+
export const BPLIST_MAGIC_AND_VERSION = Buffer.from(`${BPLIST_MAGIC}${BPLIST_VERSION}`);
|
|
8
|
+
// Binary plist header constants
|
|
9
|
+
export const BINARY_PLIST_MAGIC = 'bplist00';
|
|
10
|
+
export const IBINARY_PLIST_MAGIC = 'Ibplist00';
|
|
11
|
+
export const BINARY_PLIST_HEADER_LENGTH = 9;
|
|
12
|
+
// XML plist constants
|
|
13
|
+
export const XML_DECLARATION = '<?xml';
|
|
14
|
+
export const PLIST_CLOSING_TAG = '</plist>';
|
|
15
|
+
// Length field constants
|
|
16
|
+
export const LENGTH_FIELD_1_BYTE = 1;
|
|
17
|
+
export const LENGTH_FIELD_2_BYTES = 2;
|
|
18
|
+
export const LENGTH_FIELD_4_BYTES = 4;
|
|
19
|
+
export const LENGTH_FIELD_8_BYTES = 8;
|
|
20
|
+
export const UINT32_HIGH_MULTIPLIER = 0x100000000;
|
|
21
|
+
// Encoding constants
|
|
22
|
+
export const UTF8_ENCODING = 'utf8';
|
|
23
|
+
// Apple epoch offset (seconds between Unix epoch 1970-01-01 and Apple epoch 2001-01-01)
|
|
24
|
+
export const APPLE_EPOCH_OFFSET = 978307200;
|
|
25
|
+
// Binary plist trailer size (last 32 bytes of the file)
|
|
26
|
+
export const BPLIST_TRAILER_SIZE = 32;
|
|
27
|
+
// Object types in binary plist
|
|
28
|
+
export const BPLIST_TYPE = {
|
|
29
|
+
NULL: 0x00,
|
|
30
|
+
FALSE: 0x08,
|
|
31
|
+
TRUE: 0x09,
|
|
32
|
+
FILL: 0x0f,
|
|
33
|
+
INT: 0x10,
|
|
34
|
+
REAL: 0x20,
|
|
35
|
+
DATE: 0x30,
|
|
36
|
+
DATA: 0x40,
|
|
37
|
+
STRING_ASCII: 0x50,
|
|
38
|
+
STRING_UNICODE: 0x60,
|
|
39
|
+
UID: 0x80,
|
|
40
|
+
ARRAY: 0xa0,
|
|
41
|
+
SET: 0xc0,
|
|
42
|
+
DICT: 0xd0,
|
|
43
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createBinaryPlist } from './binary-plist-creator.js';
|
|
2
|
+
import { isBinaryPlist, parseBinaryPlist } from './binary-plist-parser.js';
|
|
3
|
+
import { APPLE_EPOCH_OFFSET, BPLIST_MAGIC_AND_VERSION, BPLIST_TYPE, UTF8_ENCODING } from './constants.js';
|
|
4
|
+
import { LengthBasedSplitter } from './length-based-splitter.js';
|
|
5
|
+
import { createPlist as createXmlPlist } from './plist-creator.js';
|
|
6
|
+
import { PlistServiceDecoder } from './plist-decoder.js';
|
|
7
|
+
import { PlistServiceEncoder } from './plist-encoder.js';
|
|
8
|
+
import { parsePlist as parseXmlPlist } from './plist-parser.js';
|
|
9
|
+
import { PlistService } from './plist-service.js';
|
|
10
|
+
import { createPlist } from './unified-plist-creator.js';
|
|
11
|
+
import { parsePlist } from './unified-plist-parser.js';
|
|
12
|
+
import { ensureString, escapeXml, findFirstReplacementCharacter, fixMultipleXmlDeclarations, hasUnicodeReplacementCharacter, isValidXml, isXmlPlistContent, trimBeforeXmlDeclaration } from './utils.js';
|
|
13
|
+
export { createPlist, createXmlPlist, createBinaryPlist, LengthBasedSplitter, parsePlist, parseXmlPlist, parseBinaryPlist, isBinaryPlist, PlistService, PlistServiceDecoder, PlistServiceEncoder, APPLE_EPOCH_OFFSET, BPLIST_MAGIC_AND_VERSION, BPLIST_TYPE, UTF8_ENCODING, hasUnicodeReplacementCharacter, findFirstReplacementCharacter, ensureString, trimBeforeXmlDeclaration, fixMultipleXmlDeclarations, isValidXml, escapeXml, isXmlPlistContent, };
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/plist/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,WAAW,EACX,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,WAAW,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,SAAS,EACT,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,UAAU,EACV,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,WAAW,EACX,aAAa,EAEb,8BAA8B,EAC9B,6BAA6B,EAC7B,YAAY,EACZ,wBAAwB,EACxB,0BAA0B,EAC1B,UAAU,EACV,SAAS,EACT,iBAAiB,GAClB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Export all components for easy imports
|
|
2
|
+
import { createBinaryPlist } from './binary-plist-creator.js';
|
|
3
|
+
import { isBinaryPlist, parseBinaryPlist } from './binary-plist-parser.js';
|
|
4
|
+
import { APPLE_EPOCH_OFFSET, BPLIST_MAGIC_AND_VERSION, BPLIST_TYPE, UTF8_ENCODING, } from './constants.js';
|
|
5
|
+
import { LengthBasedSplitter } from './length-based-splitter.js';
|
|
6
|
+
import { createPlist as createXmlPlist } from './plist-creator.js';
|
|
7
|
+
import { PlistServiceDecoder } from './plist-decoder.js';
|
|
8
|
+
import { PlistServiceEncoder } from './plist-encoder.js';
|
|
9
|
+
import { parsePlist as parseXmlPlist } from './plist-parser.js';
|
|
10
|
+
import { PlistService } from './plist-service.js';
|
|
11
|
+
import { createPlist } from './unified-plist-creator.js';
|
|
12
|
+
import { parsePlist } from './unified-plist-parser.js';
|
|
13
|
+
import { ensureString, escapeXml, findFirstReplacementCharacter, fixMultipleXmlDeclarations, hasUnicodeReplacementCharacter, isValidXml, isXmlPlistContent, trimBeforeXmlDeclaration, } from './utils.js';
|
|
14
|
+
export { createPlist, createXmlPlist, createBinaryPlist, LengthBasedSplitter, parsePlist, parseXmlPlist, parseBinaryPlist, isBinaryPlist, PlistService, PlistServiceDecoder, PlistServiceEncoder, APPLE_EPOCH_OFFSET, BPLIST_MAGIC_AND_VERSION, BPLIST_TYPE, UTF8_ENCODING,
|
|
15
|
+
// Utility functions
|
|
16
|
+
hasUnicodeReplacementCharacter, findFirstReplacementCharacter, ensureString, trimBeforeXmlDeclaration, fixMultipleXmlDeclarations, isValidXml, escapeXml, isXmlPlistContent, };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Transform, type TransformCallback } from 'stream';
|
|
2
|
+
/**
|
|
3
|
+
* Options for LengthBasedSplitter
|
|
4
|
+
*/
|
|
5
|
+
export interface LengthBasedSplitterOptions {
|
|
6
|
+
readableStream?: NodeJS.ReadableStream;
|
|
7
|
+
littleEndian?: boolean;
|
|
8
|
+
maxFrameLength?: number;
|
|
9
|
+
lengthFieldOffset?: number;
|
|
10
|
+
lengthFieldLength?: number;
|
|
11
|
+
lengthAdjustment?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Splits incoming data into length-prefixed chunks
|
|
15
|
+
*/
|
|
16
|
+
export declare class LengthBasedSplitter extends Transform {
|
|
17
|
+
private buffer;
|
|
18
|
+
private readonly littleEndian;
|
|
19
|
+
private readonly maxFrameLength;
|
|
20
|
+
private readonly lengthFieldOffset;
|
|
21
|
+
private readonly lengthFieldLength;
|
|
22
|
+
private readonly lengthAdjustment;
|
|
23
|
+
private isXmlMode;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new LengthBasedSplitter
|
|
26
|
+
* @param options Configuration options
|
|
27
|
+
*/
|
|
28
|
+
constructor(options?: LengthBasedSplitterOptions);
|
|
29
|
+
/**
|
|
30
|
+
* Shutdown the splitter and remove all listeners
|
|
31
|
+
*/
|
|
32
|
+
shutdown(): void;
|
|
33
|
+
_transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
|
|
34
|
+
/**
|
|
35
|
+
* Process data as XML
|
|
36
|
+
*/
|
|
37
|
+
private processXmlData;
|
|
38
|
+
/**
|
|
39
|
+
* Process data as binary with length prefix
|
|
40
|
+
*/
|
|
41
|
+
private processBinaryData;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=length-based-splitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"length-based-splitter.d.ts","sourceRoot":"","sources":["../../../../src/lib/plist/length-based-splitter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AA0B3D;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,SAAS,CAAkB;IAEnC;;;OAGG;gBACS,OAAO,GAAE,0BAA+B;IAkBpD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAUhB,UAAU,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI;IAuDP;;OAEG;IACH,OAAO,CAAC,cAAc;IA+CtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CA+H1B"}
|