]> pd.if.org Git - zpackage/commitdiff
add missing file
authorNathan Wagner <nw@hydaspes.if.org>
Fri, 15 Feb 2019 18:32:28 +0000 (18:32 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Fri, 15 Feb 2019 18:32:28 +0000 (18:32 +0000)
crypto/rfc3986.re [new file with mode: 0644]

diff --git a/crypto/rfc3986.re b/crypto/rfc3986.re
new file mode 100644 (file)
index 0000000..463486f
--- /dev/null
@@ -0,0 +1,224 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*!max:re2c*/
+
+struct input {
+       /*!stags:re2c format = "const char *@@;\n"; */
+};
+
+static void init_input(struct input *in) {
+       /*!stags:re2c format = "in->@@ = 0;\n"; */
+}
+
+struct tls_uri {
+       char *scheme;
+       char *userinfo;
+       char *host;
+       char *port;
+       char *path;
+       char *query;
+       char *fragment;
+};
+
+#define YYCTYPE     char
+#define YYPEEK()    *cur
+#define YYSKIP()    if (++cur > lim) return 3;
+#define YYBACKUP()  mar = cur
+#define YYRESTORE() cur = mar
+#define YYSTAGP(p) p = cur
+#define YYSTAGN(p) p = 0
+
+static int parse_uri(const char *cur, struct tls_uri *uri) {
+    const char
+        *s1, *u1, *h1, *h3, *h5, *r1, *p1, *p3, *q1, *f1,
+        *s2, *u2, *h2, *h4, *h6, *r2, *p2, *p4, *q2, *f2;
+    long c;
+    const char *mar, *lim;
+       struct input inp;
+       struct input *in = &inp;
+       init_input(in);
+
+       lim = cur + strlen(cur);
+
+    c = 0;
+loop:
+/*!re2c
+       re2c:yyfill:enable = 0;
+    re2c:tags:expression     = "in->@@";
+
+    end = "\x00";
+    eol = "\n";
+
+    alpha       = [a-zA-Z];
+    digit       = [0-9];
+    hexdigit    = [0-9a-fA-F];
+    unreserved  = alpha | digit | [-._~];
+    pct_encoded = "%" hexdigit{2};
+    sub_delims  = [!$&'()*+,;=];
+    pchar       = unreserved | pct_encoded | sub_delims | [:@];
+
+    scheme = @s1 alpha (alpha | digit | [-+.])* @s2;
+    userinfo = @u1 (unreserved | pct_encoded | sub_delims | ":")* @u2;
+    dec_octet
+        = digit
+        | [\x31-\x39] digit
+        | "1" digit{2}
+        | "2" [\x30-\x34] digit
+        | "25" [\x30-\x35];
+    ipv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet;
+    h16         = hexdigit{1,4};
+    ls32        = h16 ":" h16 | ipv4address;
+    ipv6address
+        =                            (h16 ":"){6} ls32
+        |                       "::" (h16 ":"){5} ls32
+        | (               h16)? "::" (h16 ":"){4} ls32
+        | ((h16 ":"){0,1} h16)? "::" (h16 ":"){3} ls32
+        | ((h16 ":"){0,2} h16)? "::" (h16 ":"){2} ls32
+        | ((h16 ":"){0,3} h16)? "::"  h16 ":"     ls32
+        | ((h16 ":"){0,4} h16)? "::"              ls32
+        | ((h16 ":"){0,5} h16)? "::"              h16
+        | ((h16 ":"){0,6} h16)? "::";
+    ipvfuture   = "v" hexdigit+ "." (unreserved | sub_delims | ":" )+;
+    ip_literal  = "[" ( ipv6address | ipvfuture ) "]";
+    reg_name    = (unreserved | pct_encoded | sub_delims)*;
+    host
+        = @h1 ip_literal  @h2
+        | @h3 ipv4address @h4
+        | @h5 reg_name    @h6;
+    port      = @r1 digit* @r2;
+    authority = (userinfo "@")? host (":" port)?;
+    path_abempty  = ("/" pchar*)*;
+    path_absolute = "/" (pchar+ ("/" pchar*)*)?;
+    path_rootless = pchar+ ("/" pchar*)*;
+    path_empty    = "";
+    hier_part
+        = "//" authority @p1 path_abempty @p2
+        | @p3 (path_absolute | path_rootless | path_empty) @p4;
+    query    = @q1 (pchar | [/?])* @q2;
+    fragment = @f1 (pchar | [/?])* @f2;
+    uri = scheme ":" hier_part ("?" query)? ("#" fragment)?;
+
+    *   { return 1; }
+    end { return 0; }
+    eol { goto loop; }
+    uri {
+       uri->scheme = strndup(s1, (size_t)(s2 - s1));
+        if (u1) uri->userinfo = strndup(u1, (size_t)(u2 - u1));
+        if (h1) uri->host = strndup(h1, (size_t)(h2 - h1));
+        if (h3) uri->host = strndup(h3, (size_t)(h4 - h3));
+        if (h5) uri->host = strndup(h5, (size_t)(h6 - h5));
+        if (r1) uri->port = strndup(r1, (size_t)(r2 - r1));
+        if (p1) uri->path = strndup(p1, (size_t)(p2 - p1));
+        if (p3) uri->path = strndup(p3, (size_t)(p4 - p3));
+        if (q1) uri->query = strndup(q1, (size_t)(q2 - q1));
+        if (f1) uri->fragment = strndup(f1, (size_t)(f2 - f1));
+
+       return 0;
+    }
+*/
+}
+
+static int hex(char *s) {
+       int r = 0;
+       int i;
+       for (i = 0; i < 2; i++) {
+               r *= 16;
+               switch (s[i]) {
+                       case '0': break;
+                       case '1': r += 1; break;
+                       case '2': r += 2; break;
+                       case '3': r += 3; break;
+                       case '4': r += 4; break;
+                       case '5': r += 5; break;
+                       case '6': r += 6; break;
+                       case '7': r += 7; break;
+                       case '8': r += 8; break;
+                       case '9': r += 9; break;
+                       case 'A':
+                       case 'a': r += 11; break;
+                       case 'B':
+                       case 'b': r += 11; break;
+                       case 'C':
+                       case 'c': r += 12; break;
+                       case 'D':
+                       case 'd': r += 13; break;
+                       case 'E':
+                       case 'e': r += 14; break;
+                       case 'F':
+                       case 'f': r += 15; break;
+                       default:
+                               /* This is an error, but should have
+                               been caught at the lexing stage */
+                               break;
+               }
+       }
+       return r;
+}
+
+static void percent_decode(char *s) {
+       char *d = s;
+
+       if (!s) {
+               return;
+       }
+
+       while (*s) {
+               switch (*s) {
+                       case '%':
+                               if (*(s+1) && *(s+2)) {
+                                       *d++ = hex(s+1);
+                                       s += 3;
+                               }
+                               break;
+                       default:
+                               *d++ = *s++;
+                               break;
+               }
+       }
+       *d = 0;
+}
+
+int tls_parse_uri(char *s, struct tls_uri *uri) {
+       int rv;
+
+       rv = parse_uri(s, uri);
+       if (rv != 0) {
+               return rv;
+       }
+
+       if (uri->port == NULL) {
+               if (!strcmp(uri->scheme, "http")) {
+                       uri->port = strdup("80");
+               } else if (!strcmp(uri->scheme, "https")) {
+                       uri->port = strdup("443");
+               } else if (!strcmp(uri->scheme, "ftp")) {
+                       uri->port = strdup("21");
+               } else {
+                       uri->port = strdup("0");
+               }
+       }
+
+       percent_decode(uri->host);
+       percent_decode(uri->path);
+       percent_decode(uri->query);
+
+       
+       if (uri->path == NULL || uri->path[0] == 0) {
+               free(uri->path);
+               uri->path = strdup("/");
+       }
+
+       return rv;
+}
+
+void tls_free_uri(struct tls_uri *uri) {
+       free(uri->host);
+       free(uri->path);
+       free(uri->query);
+       free(uri->port);
+       free(uri->scheme);
+}