appium-ios-remotexpc 0.5.0 → 0.5.2
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/lib/plist/length-based-splitter.d.ts.map +1 -1
- package/build/src/lib/plist/length-based-splitter.js +3 -33
- package/build/src/lib/plist/plist-decoder.js +1 -1
- package/build/src/services/ios/mobile-config/index.js +1 -1
- package/package.json +1 -1
- package/src/lib/plist/length-based-splitter.ts +7 -42
- package/src/lib/plist/plist-decoder.ts +1 -1
- package/src/services/ios/mobile-config/index.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.5.2](https://github.com/appium/appium-ios-remotexpc/compare/v0.5.1...v0.5.2) (2025-10-04)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* use binary plist for removeProfile profileIdentifier ([8848c03](https://github.com/appium/appium-ios-remotexpc/commit/8848c0327b1720c7680c9be60f83aeafde9f3c32))
|
|
6
|
+
|
|
7
|
+
## [0.5.1](https://github.com/appium/appium-ios-remotexpc/compare/v0.5.0...v0.5.1) (2025-10-04)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **plist:** enforce strict length‑prefixed framing in `LengthBasedSplitter` ([#75](https://github.com/appium/appium-ios-remotexpc/issues/75)) ([e3d1ba2](https://github.com/appium/appium-ios-remotexpc/commit/e3d1ba26bc0553a82e56e8af429dd1c1d1637e88))
|
|
12
|
+
|
|
1
13
|
## [0.5.0](https://github.com/appium/appium-ios-remotexpc/compare/v0.4.2...v0.5.0) (2025-09-29)
|
|
2
14
|
|
|
3
15
|
### Features
|
|
@@ -1 +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;
|
|
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;IA6CP;;OAEG;IACH,OAAO,CAAC,cAAc;IA+CtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAsG1B"}
|
|
@@ -57,29 +57,16 @@ export class LengthBasedSplitter extends Transform {
|
|
|
57
57
|
this.buffer = Buffer.concat([this.buffer, chunk]);
|
|
58
58
|
// Check if this is XML data or binary plist before doing any other processing
|
|
59
59
|
const bufferString = this.buffer.toString(UTF8_ENCODING, 0, Math.min(MAX_PREVIEW_LENGTH, this.buffer.length));
|
|
60
|
-
// Check for XML format
|
|
61
|
-
if (isXmlPlistContent(bufferString) || this.isXmlMode) {
|
|
62
|
-
// This is XML data, set XML mode
|
|
63
|
-
this.isXmlMode = true;
|
|
64
|
-
this.processXmlData(callback);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
60
|
// Check for binary plist format (bplist00 or Ibplist00)
|
|
68
61
|
if (this.buffer.length >= BINARY_PLIST_HEADER_LENGTH) {
|
|
69
62
|
const possibleBplistHeader = this.buffer.toString(UTF8_ENCODING, 0, BINARY_PLIST_HEADER_LENGTH);
|
|
70
63
|
if (possibleBplistHeader === BINARY_PLIST_MAGIC ||
|
|
71
64
|
possibleBplistHeader.includes(BINARY_PLIST_MAGIC)) {
|
|
72
|
-
log.debug('Detected standard binary plist format');
|
|
73
|
-
this.push(this.buffer);
|
|
74
|
-
this.buffer = Buffer.alloc(0);
|
|
75
|
-
return callback();
|
|
65
|
+
log.debug('Detected standard binary plist format; proceeding with length-prefixed frame parsing');
|
|
76
66
|
}
|
|
77
67
|
if (possibleBplistHeader === IBINARY_PLIST_MAGIC ||
|
|
78
68
|
possibleBplistHeader.includes(IBINARY_PLIST_MAGIC)) {
|
|
79
|
-
log.debug('Detected non-standard Ibplist00 format');
|
|
80
|
-
this.push(this.buffer);
|
|
81
|
-
this.buffer = Buffer.alloc(0);
|
|
82
|
-
return callback();
|
|
69
|
+
log.debug('Detected non-standard Ibplist00 format; proceeding with length-prefixed frame parsing');
|
|
83
70
|
}
|
|
84
71
|
}
|
|
85
72
|
// Process as many complete messages as possible for binary data
|
|
@@ -172,11 +159,6 @@ export class LengthBasedSplitter extends Transform {
|
|
|
172
159
|
else {
|
|
173
160
|
// If length is still invalid, check if this might actually be XML
|
|
174
161
|
const suspiciousData = this.buffer.toString(UTF8_ENCODING, 0, Math.min(MAX_PREVIEW_LENGTH, this.buffer.length));
|
|
175
|
-
if (isXmlPlistContent(suspiciousData)) {
|
|
176
|
-
this.isXmlMode = true;
|
|
177
|
-
// Process as XML on next iteration
|
|
178
|
-
return callback();
|
|
179
|
-
}
|
|
180
162
|
// Invalid length - skip one byte and try again
|
|
181
163
|
this.buffer = this.buffer.slice(1);
|
|
182
164
|
continue;
|
|
@@ -186,11 +168,6 @@ export class LengthBasedSplitter extends Transform {
|
|
|
186
168
|
// For non-4-byte length fields, just use the original approach
|
|
187
169
|
// If length is invalid, check if this might actually be XML
|
|
188
170
|
const suspiciousData = this.buffer.toString(UTF8_ENCODING, 0, Math.min(MAX_PREVIEW_LENGTH, this.buffer.length));
|
|
189
|
-
if (isXmlPlistContent(suspiciousData)) {
|
|
190
|
-
this.isXmlMode = true;
|
|
191
|
-
// Process as XML on next iteration
|
|
192
|
-
return callback();
|
|
193
|
-
}
|
|
194
171
|
// Invalid length - skip one byte and try again
|
|
195
172
|
this.buffer = this.buffer.slice(1);
|
|
196
173
|
continue;
|
|
@@ -206,14 +183,7 @@ export class LengthBasedSplitter extends Transform {
|
|
|
206
183
|
try {
|
|
207
184
|
// Extract the complete message
|
|
208
185
|
const message = this.buffer.slice(0, totalLength);
|
|
209
|
-
//
|
|
210
|
-
const messageStart = message.toString(UTF8_ENCODING, 0, Math.min(MAX_PREVIEW_LENGTH, message.length));
|
|
211
|
-
if (isXmlPlistContent(messageStart)) {
|
|
212
|
-
// Switch to XML mode
|
|
213
|
-
this.isXmlMode = true;
|
|
214
|
-
return callback();
|
|
215
|
-
}
|
|
216
|
-
// Push the message
|
|
186
|
+
// Push the message (header + payload)
|
|
217
187
|
this.push(message);
|
|
218
188
|
// Remove the processed message from the buffer
|
|
219
189
|
this.buffer = this.buffer.slice(totalLength);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logger } from '@appium/support';
|
|
2
2
|
import { Transform } from 'stream';
|
|
3
3
|
import { UTF8_ENCODING } from './constants.js';
|
|
4
|
-
import { parsePlist } from './plist-parser.js';
|
|
4
|
+
import { parsePlist } from './unified-plist-parser.js';
|
|
5
5
|
import { ensureString, findFirstReplacementCharacter, fixMultipleXmlDeclarations, hasUnicodeReplacementCharacter, } from './utils.js';
|
|
6
6
|
const log = logger.getLogger('Plist');
|
|
7
7
|
/**
|
|
@@ -133,7 +133,7 @@ class MobileConfigService extends BaseService {
|
|
|
133
133
|
};
|
|
134
134
|
const req = {
|
|
135
135
|
RequestType: 'RemoveProfile',
|
|
136
|
-
ProfileIdentifier: createPlist(payloadData),
|
|
136
|
+
ProfileIdentifier: createPlist(payloadData, true),
|
|
137
137
|
};
|
|
138
138
|
log.info(req);
|
|
139
139
|
await this._sendPlistAndReceive(req);
|
package/package.json
CHANGED
|
@@ -100,14 +100,6 @@ export class LengthBasedSplitter extends Transform {
|
|
|
100
100
|
Math.min(MAX_PREVIEW_LENGTH, this.buffer.length),
|
|
101
101
|
);
|
|
102
102
|
|
|
103
|
-
// Check for XML format
|
|
104
|
-
if (isXmlPlistContent(bufferString) || this.isXmlMode) {
|
|
105
|
-
// This is XML data, set XML mode
|
|
106
|
-
this.isXmlMode = true;
|
|
107
|
-
this.processXmlData(callback);
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
103
|
// Check for binary plist format (bplist00 or Ibplist00)
|
|
112
104
|
if (this.buffer.length >= BINARY_PLIST_HEADER_LENGTH) {
|
|
113
105
|
const possibleBplistHeader = this.buffer.toString(
|
|
@@ -120,20 +112,18 @@ export class LengthBasedSplitter extends Transform {
|
|
|
120
112
|
possibleBplistHeader === BINARY_PLIST_MAGIC ||
|
|
121
113
|
possibleBplistHeader.includes(BINARY_PLIST_MAGIC)
|
|
122
114
|
) {
|
|
123
|
-
log.debug(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return callback();
|
|
115
|
+
log.debug(
|
|
116
|
+
'Detected standard binary plist format; proceeding with length-prefixed frame parsing',
|
|
117
|
+
);
|
|
127
118
|
}
|
|
128
119
|
|
|
129
120
|
if (
|
|
130
121
|
possibleBplistHeader === IBINARY_PLIST_MAGIC ||
|
|
131
122
|
possibleBplistHeader.includes(IBINARY_PLIST_MAGIC)
|
|
132
123
|
) {
|
|
133
|
-
log.debug(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return callback();
|
|
124
|
+
log.debug(
|
|
125
|
+
'Detected non-standard Ibplist00 format; proceeding with length-prefixed frame parsing',
|
|
126
|
+
);
|
|
137
127
|
}
|
|
138
128
|
}
|
|
139
129
|
// Process as many complete messages as possible for binary data
|
|
@@ -253,12 +243,6 @@ export class LengthBasedSplitter extends Transform {
|
|
|
253
243
|
Math.min(MAX_PREVIEW_LENGTH, this.buffer.length),
|
|
254
244
|
);
|
|
255
245
|
|
|
256
|
-
if (isXmlPlistContent(suspiciousData)) {
|
|
257
|
-
this.isXmlMode = true;
|
|
258
|
-
// Process as XML on next iteration
|
|
259
|
-
return callback();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
246
|
// Invalid length - skip one byte and try again
|
|
263
247
|
this.buffer = this.buffer.slice(1);
|
|
264
248
|
continue;
|
|
@@ -272,12 +256,6 @@ export class LengthBasedSplitter extends Transform {
|
|
|
272
256
|
Math.min(MAX_PREVIEW_LENGTH, this.buffer.length),
|
|
273
257
|
);
|
|
274
258
|
|
|
275
|
-
if (isXmlPlistContent(suspiciousData)) {
|
|
276
|
-
this.isXmlMode = true;
|
|
277
|
-
// Process as XML on next iteration
|
|
278
|
-
return callback();
|
|
279
|
-
}
|
|
280
|
-
|
|
281
259
|
// Invalid length - skip one byte and try again
|
|
282
260
|
this.buffer = this.buffer.slice(1);
|
|
283
261
|
continue;
|
|
@@ -298,20 +276,7 @@ export class LengthBasedSplitter extends Transform {
|
|
|
298
276
|
// Extract the complete message
|
|
299
277
|
const message = this.buffer.slice(0, totalLength);
|
|
300
278
|
|
|
301
|
-
//
|
|
302
|
-
const messageStart = message.toString(
|
|
303
|
-
UTF8_ENCODING,
|
|
304
|
-
0,
|
|
305
|
-
Math.min(MAX_PREVIEW_LENGTH, message.length),
|
|
306
|
-
);
|
|
307
|
-
|
|
308
|
-
if (isXmlPlistContent(messageStart)) {
|
|
309
|
-
// Switch to XML mode
|
|
310
|
-
this.isXmlMode = true;
|
|
311
|
-
return callback();
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Push the message
|
|
279
|
+
// Push the message (header + payload)
|
|
315
280
|
this.push(message);
|
|
316
281
|
|
|
317
282
|
// Remove the processed message from the buffer
|
|
@@ -2,7 +2,7 @@ import { logger } from '@appium/support';
|
|
|
2
2
|
import { Transform, type TransformCallback } from 'stream';
|
|
3
3
|
|
|
4
4
|
import { UTF8_ENCODING } from './constants.js';
|
|
5
|
-
import { parsePlist } from './plist-parser.js';
|
|
5
|
+
import { parsePlist } from './unified-plist-parser.js';
|
|
6
6
|
import {
|
|
7
7
|
ensureString,
|
|
8
8
|
findFirstReplacementCharacter,
|