summaryrefslogtreecommitdiffstats
path: root/src/zvalidation.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/zvalidation.js')
-rw-r--r--src/zvalidation.js130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/zvalidation.js b/src/zvalidation.js
new file mode 100644
index 0000000..e8618e9
--- /dev/null
+++ b/src/zvalidation.js
@@ -0,0 +1,130 @@
+"use strict";
+
+var Zmodem = module.exports;
+
+Object.assign(
+ Zmodem,
+ require("./zerror")
+);
+
+const LOOKS_LIKE_ZMODEM_HEADER = /\*\x18[AC]|\*\*\x18B/;
+
+function _validate_number(key, value) {
+ if (value < 0) {
+ throw new Zmodem.Error("validation", "“" + key + "” (" + value + ") must be nonnegative.");
+ }
+
+ if (value !== Math.floor(value)) {
+ throw new Zmodem.Error("validation", "“" + key + "” (" + value + ") must be an integer.");
+ }
+}
+
+/** Validation logic for zmodem.js
+ *
+ * @exports Validation
+ */
+Zmodem.Validation = {
+
+ /**
+ * Validates and normalizes a set of parameters for an offer to send.
+ * NOTE: This returns “mtime” as epoch seconds, not a Date. This is
+ * inconsistent with the get_details() method in Session, but it’s
+ * more useful for sending over the wire.
+ *
+ * @param {FileDetails} params - The file details. Some fairly trivial
+ * variances from the specification are allowed.
+ *
+ * @return {FileDetails} The parameters that should be sent. `mtime`
+ * will be a Date rather than a number.
+ */
+ offer_parameters: function offer_parameters(params) {
+ if (!params.name) {
+ throw new Zmodem.Error("validation", "Need “name”!");
+ }
+
+ if (typeof params.name !== "string") {
+ throw new Zmodem.Error("validation", "“name” (" + params.name + ") must be a string!");
+ }
+
+ //So that we can override values as is useful
+ //without affecting the passed-in object.
+ params = Object.assign({}, params);
+
+ if (LOOKS_LIKE_ZMODEM_HEADER.test(params.name)) {
+ console.warn("The filename " + JSON.stringify(name) + " contains characters that look like a ZMODEM header. This could corrupt the ZMODEM session; consider renaming it so that the filename doesn’t contain control characters.");
+ }
+
+ if (params.serial !== null && params.serial !== undefined) {
+ throw new Zmodem.Error("validation", "“serial” is meaningless.");
+ }
+
+ params.serial = null;
+
+ ["size", "mode", "files_remaining", "bytes_remaining"].forEach(
+ function(k) {
+ var ok;
+ switch (typeof params[k]) {
+ case "object":
+ ok = (params[k] === null);
+ break;
+ case "undefined":
+ params[k] = null;
+ ok = true;
+ break;
+ case "number":
+ _validate_number(k, params[k]);
+
+ ok = true;
+ break;
+ }
+
+ if (!ok) {
+ throw new Zmodem.Error("validation", "“" + k + "” (" + params[k] + ") must be null, undefined, or a number.");
+ }
+ }
+ );
+
+ if (typeof params.mode === "number") {
+ params.mode |= 0x8000;
+ }
+
+ if (params.files_remaining === 0) {
+ throw new Zmodem.Error("validation", "“files_remaining”, if given, must be positive.");
+ }
+
+ var mtime_ok;
+ switch (typeof params.mtime) {
+ case "object":
+ mtime_ok = true;
+
+ if (params.mtime instanceof Date) {
+
+ var date_obj = params.mtime;
+ params.mtime = Math.floor( date_obj.getTime() / 1000 );
+ if (params.mtime < 0) {
+ throw new Zmodem.Error("validation", "“mtime” (" + date_obj + ") must not be earlier than 1970.");
+ }
+ }
+ else if (params.mtime !== null) {
+ mtime_ok = false;
+ }
+
+ break;
+
+ case "undefined":
+ params.mtime = null;
+ mtime_ok = true;
+ break;
+ case "number":
+ _validate_number("mtime", params.mtime);
+ mtime_ok = true;
+ break;
+ }
+
+ if (!mtime_ok) {
+ throw new Zmodem.Error("validation", "“mtime” (" + params.mtime + ") must be null, undefined, a Date, or a number.");
+ }
+
+ return params;
+ },
+};