Bug 775038 - Part 1: fix various minor defects, r=philikon

* Document Address.decode()
* Merge CharsetEncodedString into EncodedStringValue
* Merge ClassIdentifier into MessageClassValue
* Export missed coder objects and fix test scripts as well
* ReplyChargingValue is defined in MmsPduHelper, not WspPduHelper
* Fix multiple decode test cases data
* Char-set value in EncodedStringValue should be decoded as IntegerValue
* Don't insert per PDU typeinfo into decoded MMS message object
* "Date" is also a mandatory field for M-Retrieve.req PDU.
This commit is contained in:
Vicamo Yang 2012-07-23 10:20:34 +08:00
Родитель 196cffe61b
Коммит a237cd8ce1
5 изменённых файлов: 154 добавлений и 199 удалений

Просмотреть файл

@ -70,7 +70,13 @@ let BooleanValue = {
* @see OMA-TS-MMS_ENC-V1_3-20110913-A section 8
*/
let Address = {
decode: function (data) {
/**
* @param data
* A wrapped object to store encoded raw data.
*
* @return An object of two string-typed attributes: address and type.
*/
decode: function decode(data) {
let str = EncodedStringValue.decode(data);
let result;
@ -398,30 +404,15 @@ let Parameter = {
};
/**
* The Char-set values are registered by IANA as MIBEnum value and SHALL be
* encoded as Integer-value.
*
* Encoded-string-value = Text-string | Value-length Char-set Text-string
* The Char-set values are registered by IANA as MIBEnum value.
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.19
* @see OMA-TS-MMS_CONF-V1_3-20110913-A clause 10.2.1
*/
let EncodedStringValue = {
/**
* @param data
* A wrapped object containing raw PDU data.
*
* @return Decoded string.
*/
decode: function decode(data) {
return WSP.decodeAlternatives(data, null,
WSP.TextString, CharsetEncodedString);
},
};
/**
* Charset-encoded-string = Value-length Char-set Text-string
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.19
*/
let CharsetEncodedString = {
/**
* @param data
* A wrapped object containing raw PDU data.
@ -432,11 +423,11 @@ let CharsetEncodedString = {
* @throws NotWellKnownEncodingError if decoded well-known charset number is
* not registered or supported.
*/
decode: function decode(data) {
decodeCharsetEncodedString: function decodeCharsetEncodedString(data) {
let length = WSP.ValueLength.decode(data);
let end = data.offset + length;
let charset = WSP.ShortInteger.decode(data);
let charset = WSP.IntegerValue.decode(data);
let entry = WSP.WSP_WELL_KNOWN_CHARSETS[charset];
if (!entry) {
throw new WSP.NotWellKnownEncodingError(
@ -477,11 +468,27 @@ let CharsetEncodedString = {
return str;
},
/**
* @param data
* A wrapped object containing raw PDU data.
*
* @return Decoded string.
*/
decode: function decode(data) {
let begin = data.offset;
try {
return WSP.TextString.decode(data);
} catch (e) {
data.offset = begin;
return this.decodeCharsetEncodedString(data);
}
},
};
/**
* Expiry-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value)
* Address-token = <Octet 128>
* Absolute-token = <Octet 128>
* Relative-token = <Octet 129>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.20
@ -531,7 +538,8 @@ let FromValue = {
* @param data
* A wrapped object containing raw PDU data.
*
* @return Decoded string or null for MMS Proxy-Relay Insert-Address mode.
* @return A decoded Address-value or null for MMS Proxy-Relay Insert-Address
* mode.
*
* @throws CodeError if decoded token equals to neither 128 nor 129.
*/
@ -619,32 +627,15 @@ let PreviouslySentDateValue = {
/**
* Message-class-value = Class-identifier | Token-text
* Class-identifier = Personal | Advertisement | Informational | Auto
* Personal = <Octet 128>
* Advertisement = <Octet 129>
* Informational = <Octet 130>
* Auto = <Octet 131>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.27
*/
let MessageClassValue = {
/**
* @param data
* A wrapped object containing raw PDU data.
*
* @return A decoded string.
*/
decode: function decode(data) {
return WSP.decodeAlternatives(data, null,
ClassIdentifier, WSP.TokenText);
},
};
/**
* Class-identifier = Personal | Advertisement | Informational | Auto
* Personal = <Octet 128>
* Advertisement = <Octet 129>
* Informational = <Octet 130>
* Auto = <Octet 131>
*
* @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.27
*/
let ClassIdentifier = {
/**
* @param data
* A wrapped object containing raw PDU data.
@ -653,7 +644,7 @@ let ClassIdentifier = {
*
* @throws CodeError if decoded value is not in the range 128..131.
*/
decode: function decode(data) {
decodeClassIdentifier: function decodeClassIdentifier(data) {
let value = WSP.Octet.decode(data);
switch (value) {
case 128: return "personal";
@ -664,6 +655,22 @@ let ClassIdentifier = {
throw new WSP.CodeError("Class-identifier: invalid id " + value);
},
/**
* @param data
* A wrapped object containing raw PDU data.
*
* @return A decoded string.
*/
decode: function decode(data) {
let begin = data.offset;
try {
return this.decodeClassIdentifier(data);
} catch (e) {
data.offset = begin;
return WSP.TokenText.decode(data);
}
},
};
/**
@ -720,7 +727,7 @@ let MmFlagsValue = {
* A wrapped object containing raw PDU data.
*
* @return Decoded object containing an integer `type` and an string-typed
* `address` attributes.
* `text` attributes.
*
* @throws CodeError if decoded value is not in the range 128..130.
*/
@ -1020,11 +1027,13 @@ let PduHelper = {
/**
* Check existences of all mandatory fields of a MMS message. Also sets `type`
* and `typeinfo` for convient access.
* for convenient access.
*
* @param msg
* A MMS message object.
*
* @return The corresponding entry in MMS_PDU_TYPES;
*
* @throws FatalCodeError if the PDU type is not supported yet.
*/
checkMandatoryFields: function checkMandatoryFields(msg) {
@ -1039,9 +1048,10 @@ let PduHelper = {
WSP.ensureHeader(msg.headers, name);
});
// Setup convient alias that referenced frequently.
// Setup convenient alias that referenced frequently.
msg.type = type;
msg.typeinfo = entry;
return entry;
},
/**
@ -1061,9 +1071,8 @@ let PduHelper = {
msg.headers = this.parseHeaders(data, msg.headers);
// Validity checks
this.checkMandatoryFields(msg);
if (msg.typeinfo.hasContent) {
let typeinfo = this.checkMandatoryFields(msg);
if (typeinfo.hasContent) {
this.parseContent(data, msg);
}
} catch (e) {
@ -1161,7 +1170,7 @@ let PduHelper = {
try {
// Validity checks
this.checkMandatoryFields(msg);
let typeinfo = this.checkMandatoryFields(msg);
let data = this.encodeHeaders(null, msg.headers);
debug("Composed PDU Header: " + JSON.stringify(data.array));
@ -1195,6 +1204,7 @@ const MMS_PDU_TYPES = (function () {
"x-mms-content-location"]);
add(MMS_PDU_TYPE_RETRIEVE_CONF, true, ["x-mms-message-type",
"x-mms-mms-version",
"date",
"content-type"]);
add(MMS_PDU_TYPE_NOTIFYRESP_IND, false, ["x-mms-message-type",
"x-mms-transaction-id",
@ -1247,7 +1257,7 @@ const MMS_HEADER_FIELDS = (function () {
add("x-mms-retrieve-status", 0x19, RetrieveStatusValue);
add("x-mms-retrieve-text", 0x1A, EncodedStringValue);
//add("x-mms-read-status", 0x1B);
add("x-mms-reply-charging", 0x1C, WSP.ReplyChargingValue);
add("x-mms-reply-charging", 0x1C, ReplyChargingValue);
add("x-mms-reply-charging-deadline", 0x1D, ExpiryValue);
add("x-mms-reply-charging-id", 0x1E, WSP.TextString);
add("x-mms-reply-charging-size", 0x1F, WSP.LongInteger);
@ -1330,12 +1340,16 @@ const EXPORTED_SYMBOLS = ALL_CONST_SYMBOLS.concat([
"EncodedStringValue",
"ExpiryValue",
"FromValue",
"PreviouslySentByValue",
"PreviouslySentDateValue",
"MessageClassValue",
"ClassIdentifier",
"MessageTypeValue",
"MmFlagsValue",
"MmStateValue",
"PriorityValue",
"RecommendedRetrievalModeValue",
"ReplyChargingValue",
"RetrieveStatusValue",
"StatusValue",
// Parser

Просмотреть файл

@ -697,7 +697,7 @@ let ShortInteger = {
* @throws CodeError if the octet read is larger-equal than 0x80.
*/
encode: function encode(data, value) {
if (value & 0x80) {
if (value >= 0x80) {
throw new CodeError("Short-integer: invalid value " + value);
}

Просмотреть файл

@ -54,7 +54,7 @@ function wsp_test_func(func, data, expect) {
let result_str = JSON.stringify(func(data));
let expect_str = JSON.stringify(expect);
if (result_str !== expect_str) {
do_throw("expect decoded value: '" + expect_str + "', got '" + result_str + "'");
do_throw("expect value: '" + expect_str + "', got '" + result_str + "'");
}
}

Просмотреть файл

@ -263,19 +263,9 @@ add_test(function test_EncodedStringValue_decode() {
.createInstance(Ci.nsIScriptableUnicodeConverter);
conv.charset = entry.converter;
let raw;
try {
let raw = conv.convertToByteArray(str).concat([0]);
if (raw[0] >= 128) {
wsp_decode_test(MMS.EncodedStringValue,
[raw.length + 2, 0x80 | entry.number, 127].concat(raw), str);
} else {
wsp_decode_test(MMS.EncodedStringValue,
[raw.length + 1, 0x80 | entry.number].concat(raw), str);
}
} catch (e) {
do_print("Can't convert test string to byte array with " + entry.converter);
}
}
run_next_test();
@ -291,7 +281,7 @@ add_test(function test_ExpiryValue_decode() {
// Test for Absolute-token Date-value
wsp_decode_test(MMS.ExpiryValue, [3, 128, 1, 0x80], new Date(0x80 * 1000));
// Test for Relative-token Delta-seconds-value
wsp_decode_test(MMS.ExpiryValue, [3, 129, 0x80], 0);
wsp_decode_test(MMS.ExpiryValue, [2, 129, 0x80], 0);
run_next_test();
});
@ -334,7 +324,7 @@ add_test(function test_FromValue_decode() {
wsp_decode_test(MMS.FromValue, [1, 129], null);
// Test for Address-present-token:
let (addr = strToCharCodeArray("+123/TYPE=PLMN")) {
wsp_decode_test(MMS.FromValue, [addr.length + 2, 128].concat(addr),
wsp_decode_test(MMS.FromValue, [addr.length + 1, 128].concat(addr),
{address: "+123", type: "PLMN"});
}
@ -345,6 +335,28 @@ add_test(function test_FromValue_decode() {
// Test target: MessageClassValue
//
//// MessageClassValue.decodeClassIdentifier ////
add_test(function test_MessageClassValue_decodeClassIdentifier() {
let (IDs = ["personal", "advertisement", "informational", "auto"]) {
for (let i = 0; i < 256; i++) {
if ((i >= 128) && (i <= 131)) {
wsp_decode_test_ex(function (data) {
return MMS.MessageClassValue.decodeClassIdentifier(data);
}, [i], IDs[i - 128]
);
} else {
wsp_decode_test_ex(function (data) {
return MMS.MessageClassValue.decodeClassIdentifier(data);
}, [i], null, "CodeError"
);
}
}
}
run_next_test();
});
//// MessageClassValue.decode ////
add_test(function test_MessageClassValue_decode() {
@ -354,26 +366,6 @@ add_test(function test_MessageClassValue_decode() {
run_next_test();
});
//
// Test target: ClassIdentifier
//
//// ClassIdentifier.decode ////
add_test(function test_ClassIdentifier_decode() {
let (IDs = ["personal", "advertisement", "informational", "auto"]) {
for (let i = 0; i < 256; i++) {
if ((i >= 128) && (i <= 131)) {
wsp_decode_test(MMS.ClassIdentifier, [i], IDs[i - 128]);
} else {
wsp_decode_test(MMS.ClassIdentifier, [i], null, "CodeError");
}
}
}
run_next_test();
});
//
// Test target: MessageTypeValue
//
@ -433,9 +425,9 @@ add_test(function test_MmFlagsValue_decode() {
add_test(function test_MmStateValue_decode() {
for (let i = 0; i < 256; i++) {
if ((i >= 128) && (i <= 132)) {
wsp_decode_test(MMS.MmStateValue, [i, 0], i);
wsp_decode_test(MMS.MmStateValue, [i], i);
} else {
wsp_decode_test(MMS.MmStateValue, [i, 0], null, "CodeError");
wsp_decode_test(MMS.MmStateValue, [i], null, "CodeError");
}
}

Просмотреть файл

@ -27,35 +27,21 @@ add_test(function test_ensureHeader() {
//
add_test(function test_skipValue() {
function func(data) {
return WSP.skipValue(data);
}
// Test for zero-valued first octet:
wsp_decode_test_ex(function (data) {
return WSP.skipValue(data);
}, [0], null
);
wsp_decode_test_ex(func, [0], null);
// Test first octet < 31
wsp_decode_test_ex(function (data) {
return WSP.skipValue(data);
}, [1, 2], [2]
);
wsp_decode_test_ex(func, [1, 2], [2]);
// Test first octet = 31
wsp_decode_test_ex(function (data) {
return WSP.skipValue(data);
}, [31, 0], null
);
wsp_decode_test_ex(function (data) {
return WSP.skipValue(data);
}, [31, 1, 2], [2]
);
wsp_decode_test_ex(func, [31, 0], null);
wsp_decode_test_ex(func, [31, 1, 2], [2]);
// Test first octet <= 127
wsp_decode_test_ex(function (data) {
return WSP.skipValue(data);
}, strToCharCodeArray("Hello world!"), "Hello world!"
);
wsp_decode_test_ex(func, strToCharCodeArray("Hello world!"), "Hello world!");
// Test first octet >= 128
wsp_decode_test_ex(function (data) {
return WSP.skipValue(data);
}, [0x80 | 0x01], 0x01
);
wsp_decode_test_ex(func, [0x80 | 0x01], 0x01);
run_next_test();
});
@ -561,41 +547,26 @@ add_test(function test_UriValue_decode() {
//// Parameter.decodeTypedParameter ////
add_test(function test_Parameter_decodeTypedParameter() {
function func(data) {
return WSP.Parameter.decodeTypedParameter(data);
}
// Test for array-typed return value from IntegerValue
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeTypedParameter(data);
}, [7, 0, 0, 0, 0, 0, 0, 0], null, "CodeError"
);
wsp_decode_test_ex(func, [7, 0, 0, 0, 0, 0, 0, 0], null, "CodeError");
// Test for number-typed return value from IntegerValue
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeTypedParameter(data);
}, [1, 0, 0], {name: "q", value: null}
);
wsp_decode_test_ex(func, [1, 0, 0], {name: "q", value: null});
// Test for NotWellKnownEncodingError
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeTypedParameter(data);
}, [1, 0xFF], null, "NotWellKnownEncodingError"
);
wsp_decode_test_ex(func, [1, 0xFF], null, "NotWellKnownEncodingError");
// Test for parameter specific decoder
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeTypedParameter(data);
}, [1, 0, 100], {name: "q", value: 0.99}
);
wsp_decode_test_ex(func, [1, 0, 100], {name: "q", value: 0.99});
// Test for TextValue
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeTypedParameter(data);
}, [1, 0x10, 48, 46, 57, 57, 0], {name: "secure", value: "0.99"}
);
wsp_decode_test_ex(func, [1, 0x10, 48, 46, 57, 57, 0],
{name: "secure", value: "0.99"});
// Test for TextString
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeTypedParameter(data);
}, [1, 0x19, 60, 115, 109, 105, 108, 62, 0], {name: "start", value: "<smil>"}
);
wsp_decode_test_ex(func, [1, 0x19, 60, 115, 109, 105, 108, 62, 0],
{name: "start", value: "<smil>"});
// Test for skipValue
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeTypedParameter(data);
}, [1, 0x19, 128], null
);
wsp_decode_test_ex(func, [1, 0x19, 128], null);
run_next_test();
});
@ -603,24 +574,16 @@ add_test(function test_Parameter_decodeTypedParameter() {
//// Parameter.decodeUntypedParameter ////
add_test(function test_Parameter_decodeUntypedParameter() {
wsp_decode_test_ex(function (data) {
function func (data) {
return WSP.Parameter.decodeUntypedParameter(data);
}, [1], null, "CodeError"
);
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeUntypedParameter(data);
}, [65, 0, 0], {name: "a", value: null}
);
}
wsp_decode_test_ex(func, [1], null, "CodeError");
wsp_decode_test_ex(func, [65, 0, 0], {name: "a", value: null});
// Test for IntegerValue
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeUntypedParameter(data);
}, [65, 0, 1, 0], {name: "a", value: 0}
);
wsp_decode_test_ex(func, [65, 0, 1, 0], {name: "a", value: 0});
// Test for TextValue
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decodeUntypedParameter(data);
}, [65, 0, 66, 0], {name: "a", value: "B"}
);
wsp_decode_test_ex(func, [65, 0, 66, 0], {name: "a", value: "B"});
run_next_test();
});
@ -628,14 +591,9 @@ add_test(function test_Parameter_decodeUntypedParameter() {
//// Parameter.decode ////
add_test(function test_Parameter_decode() {
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decode(data);
}, [1, 0x19, 60, 115, 109, 105, 108, 62, 0], {name: "start", value: "<smil>"}
);
wsp_decode_test_ex(function (data) {
return WSP.Parameter.decode(data);
}, [65, 0, 66, 0], {name: "a", value: "B"}
);
wsp_decode_test(WSP.Parameter, [1, 0x19, 60, 115, 109, 105, 108, 62, 0],
{name: "start", value: "<smil>"});
wsp_decode_test(WSP.Parameter, [65, 0, 66, 0], {name: "a", value: "B"});
run_next_test();
});
@ -797,21 +755,17 @@ add_test(function test_WellKnownCharset_decode() {
//// ContentTypeValue.decodeConstrainedMedia ////
add_test(function test_ContentTypeValue_decodeConstrainedMedia() {
function func(data) {
return WSP.ContentTypeValue.decodeConstrainedMedia(data);
}
// Test for string-typed return value from ConstrainedEncoding
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeConstrainedMedia(data);
}, [65, 0], {media: "a", params: null}
);
wsp_decode_test_ex(func, [65, 0], {media: "a", params: null});
// Test for number-typed return value from ConstrainedEncoding
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeConstrainedMedia(data);
}, [0x33 | 0x80], {media: "application/vnd.wap.multipart.related", params: null}
);
wsp_decode_test_ex(func, [0x33 | 0x80],
{media: "application/vnd.wap.multipart.related", params: null});
// Test for NotWellKnownEncodingError
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeConstrainedMedia(data);
}, [0x80], null, "NotWellKnownEncodingError"
);
wsp_decode_test_ex(func, [0x80], null, "NotWellKnownEncodingError");
run_next_test();
});
@ -819,20 +773,15 @@ add_test(function test_ContentTypeValue_decodeConstrainedMedia() {
//// ContentTypeValue.decodeMedia ////
add_test(function test_ContentTypeValue_decodeMedia() {
function func(data) {
return WSP.ContentTypeValue.decodeMedia(data);
}
// Test for NullTerminatedTexts
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeMedia(data);
}, [65, 0], "a"
);
wsp_decode_test_ex(func, [65, 0], "a");
// Test for IntegerValue
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeMedia(data);
}, [0x3E | 0x80], "application/vnd.wap.mms-message"
);
wsp_decode_test_ex(function (data) {
return WSP.ContentTypeValue.decodeMedia(data);
}, [0x80], null, "NotWellKnownEncodingError"
);
wsp_decode_test_ex(func, [0x3E | 0x80], "application/vnd.wap.mms-message");
wsp_decode_test_ex(func, [0x80], null, "NotWellKnownEncodingError");
run_next_test();
});