appium-ios-remotexpc 0.5.0 → 0.5.1

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 CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.5.1](https://github.com/appium/appium-ios-remotexpc/compare/v0.5.0...v0.5.1) (2025-10-04)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **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))
6
+
1
7
  ## [0.5.0](https://github.com/appium/appium-ios-remotexpc/compare/v0.4.2...v0.5.0) (2025-09-29)
2
8
 
3
9
  ### 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;IAuDP;;OAEG;IACH,OAAO,CAAC,cAAc;IA+CtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CA+H1B"}
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
- // Check if this message is actually XML
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-ios-remotexpc",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "main": "build/src/index.js",
5
5
  "types": "build/src/index.d.ts",
6
6
  "type": "module",
@@ -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('Detected standard binary plist format');
124
- this.push(this.buffer);
125
- this.buffer = Buffer.alloc(0);
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('Detected non-standard Ibplist00 format');
134
- this.push(this.buffer);
135
- this.buffer = Buffer.alloc(0);
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
- // Check if this message is actually XML
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,