diff options
Diffstat (limited to 'dom/system/gonk/tests/test_ril_worker_buf.js')
-rw-r--r-- | dom/system/gonk/tests/test_ril_worker_buf.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/dom/system/gonk/tests/test_ril_worker_buf.js b/dom/system/gonk/tests/test_ril_worker_buf.js new file mode 100644 index 000000000..30054a881 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_buf.js @@ -0,0 +1,187 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + run_next_test(); +} + +/** + * Add test function with specified parcel and request handler. + * + * @param parcel + * Incoming parcel to be tested. + * @param handler + * Handler to be invoked as RIL request handler. + */ +function add_test_incoming_parcel(parcel, handler) { + add_test(function test_incoming_parcel() { + let worker = newWorker({ + postRILMessage: function(data) { + // do nothing + }, + postMessage: function(message) { + // do nothing + } + }); + + if (!parcel) { + parcel = newIncomingParcel(-1, + worker.RESPONSE_TYPE_UNSOLICITED, + worker.REQUEST_VOICE_REGISTRATION_STATE, + [0, 0, 0, 0]); + } + + let context = worker.ContextPool._contexts[0]; + // supports only requests less or equal than UINT8_MAX(255). + let buf = context.Buf; + let request = parcel[buf.PARCEL_SIZE_SIZE + buf.UINT32_SIZE]; + context.RIL[request] = function ril_request_handler() { + handler.apply(this, arguments); + }; + + worker.onRILMessage(0, parcel); + + // end of incoming parcel's trip, let's do next test. + run_next_test(); + }); +} + +// Test normal parcel handling. +add_test_incoming_parcel(null, + function test_normal_parcel_handling() { + let self = this; + try { + // reads exactly the same size, should not throw anything. + self.context.Buf.readInt32(); + } catch (e) { + ok(false, "Got exception: " + e); + } + } +); + +// Test parcel under read. +add_test_incoming_parcel(null, + function test_parcel_under_read() { + let self = this; + try { + // reads less than parcel size, should not throw. + self.context.Buf.readUint16(); + } catch (e) { + ok(false, "Got exception: " + e); + } + } +); + +// Test parcel over read. +add_test_incoming_parcel(null, + function test_parcel_over_read() { + let buf = this.context.Buf; + + // read all data available + while (buf.readAvailable > 0) { + buf.readUint8(); + } + + throws(function over_read_handler() { + // reads more than parcel size, should throw an error. + buf.readUint8(); + },"Trying to read data beyond the parcel end!"); + } +); + +// Test Bug 814761: buffer overwritten +add_test(function test_incoming_parcel_buffer_overwritten() { + let worker = newWorker({ + postRILMessage: function(data) { + // do nothing + }, + postMessage: function(message) { + // do nothing + } + }); + + let context = worker.ContextPool._contexts[0]; + // A convenient alias. + let buf = context.Buf; + + // Allocate an array of specified size and set each of its elements to value. + function calloc(length, value) { + let array = new Array(length); + for (let i = 0; i < length; i++) { + array[i] = value; + } + return array; + } + + // Do nothing in handleParcel(). + let request = worker.REQUEST_VOICE_REGISTRATION_STATE; + context.RIL[request] = null; + + // Prepare two parcels, whose sizes are both smaller than the incoming buffer + // size but larger when combined, to trigger the bug. + let pA_dataLength = buf.incomingBufferLength / 2; + let pA = newIncomingParcel(-1, + worker.RESPONSE_TYPE_UNSOLICITED, + request, + calloc(pA_dataLength, 1)); + let pA_parcelSize = pA.length - buf.PARCEL_SIZE_SIZE; + + let pB_dataLength = buf.incomingBufferLength * 3 / 4; + let pB = newIncomingParcel(-1, + worker.RESPONSE_TYPE_UNSOLICITED, + request, + calloc(pB_dataLength, 1)); + let pB_parcelSize = pB.length - buf.PARCEL_SIZE_SIZE; + + // First, send an incomplete pA and verifies related data pointer: + let p1 = pA.subarray(0, pA.length - 1); + worker.onRILMessage(0, p1); + // The parcel should not have been processed. + equal(buf.readAvailable, 0); + // buf.currentParcelSize should have been set because incoming data has more + // than 4 octets. + equal(buf.currentParcelSize, pA_parcelSize); + // buf.readIncoming should contains remaining unconsumed octets count. + equal(buf.readIncoming, p1.length - buf.PARCEL_SIZE_SIZE); + // buf.incomingWriteIndex should be ready to accept the last octet. + equal(buf.incomingWriteIndex, p1.length); + + // Second, send the last octet of pA and whole pB. The Buf should now expand + // to cover both pA & pB. + let p2 = new Uint8Array(1 + pB.length); + p2.set(pA.subarray(pA.length - 1), 0); + p2.set(pB, 1); + worker.onRILMessage(0, p2); + // The parcels should have been both consumed. + equal(buf.readAvailable, 0); + // No parcel data remains. + equal(buf.currentParcelSize, 0); + // No parcel data remains. + equal(buf.readIncoming, 0); + // The Buf should now expand to cover both pA & pB. + equal(buf.incomingWriteIndex, pA.length + pB.length); + + // end of incoming parcel's trip, let's do next test. + run_next_test(); +}); + +// Test Buf.readUint8Array. +add_test_incoming_parcel(null, + function test_buf_readUint8Array() { + let buf = this.context.Buf; + + let u8array = buf.readUint8Array(1); + equal(u8array instanceof Uint8Array, true); + equal(u8array.length, 1); + equal(buf.readAvailable, 3); + + u8array = buf.readUint8Array(2); + equal(u8array.length, 2); + equal(buf.readAvailable, 1); + + throws(function over_read_handler() { + // reads more than parcel size, should throw an error. + u8array = buf.readUint8Array(2); + }, "Trying to read data beyond the parcel end!"); + } +); |