diff libutil/alpha_valid.c @ 157:f064dbcc5f41

libutil split from libcommon
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 26 Feb 2021 20:19:58 +0000
parents libcommon/alpha_valid.c@f7145c77b7fb
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libutil/alpha_valid.c	Fri Feb 26 20:19:58 2021 +0000
@@ -0,0 +1,152 @@
+/*
+ * This module contains functions for validating alpha fields
+ * that exist in various SIM files.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static
+validate_classic_gsm(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp;
+	unsigned n;
+
+	dp = data;
+	for (n = 0; n < nbytes; n++) {
+		if (*dp == 0xFF)
+			break;
+		if (*dp & 0x80)
+			return(-1);
+		dp++;
+	}
+	if (textlenp)
+		*textlenp = n;
+	for (; n < nbytes; n++)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_ucs2_80(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp, *endp;
+
+	if (nbytes < 3)
+		return(-1);
+	dp = data + 1;
+	endp = data + nbytes;
+	while (dp < endp) {
+		if (dp + 1 == endp) {
+			if (*dp != 0xFF)
+				return(-1);
+			if (textlenp)
+				*textlenp = dp - data;
+			return(0);
+		}
+		if (dp[0] == 0xFF && dp[1] == 0xFF)
+			break;
+		dp += 2;
+	}
+	if (textlenp)
+		*textlenp = dp - data;
+	while (dp < endp)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_ucs2_81(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp, *endp;
+	unsigned textlen;
+
+	if (nbytes < 4)
+		return(-1);
+	if (!data[1])
+		return(-1);
+	textlen = data[1] + 3;
+	if (textlen > nbytes)
+		return(-1);
+	if (textlenp)
+		*textlenp = textlen;
+	dp = data + textlen;
+	endp = data + nbytes;
+	while (dp < endp)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_ucs2_82(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp, *endp;
+	unsigned textlen;
+
+	if (nbytes < 5)
+		return(-1);
+	if (!data[1])
+		return(-1);
+	textlen = data[1] + 4;
+	if (textlen > nbytes)
+		return(-1);
+	if (textlenp)
+		*textlenp = textlen;
+	dp = data + textlen;
+	endp = data + nbytes;
+	while (dp < endp)
+		if (*dp++ != 0xFF)
+			return(-1);
+	return(0);
+}
+
+static
+validate_empty(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	u_char *dp;
+	unsigned n;
+
+	dp = data;
+	for (n = 0; n < nbytes; n++)
+		if (*dp++ != 0xFF)
+			return(-1);
+	if (textlenp)
+		*textlenp = 0;
+	return(0);
+}
+
+validate_alpha_field(data, nbytes, textlenp)
+	u_char *data;
+	unsigned nbytes, *textlenp;
+{
+	if (data[0] < 0x80)
+		return validate_classic_gsm(data, nbytes, textlenp);
+	switch (data[0]) {
+	case 0x80:
+		return validate_ucs2_80(data, nbytes, textlenp);
+	case 0x81:
+		return validate_ucs2_81(data, nbytes, textlenp);
+	case 0x82:
+		return validate_ucs2_82(data, nbytes, textlenp);
+	case 0xFF:
+		return validate_empty(data, nbytes, textlenp);
+	default:
+		return -1;
+	}
+}