💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › d8dd956b23080fc5ff10750e15781… captured on 2024-02-05 at 09:54:06. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
0 /*
1 * ISC License
2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include <string.h>
8 #include <time.h>
9 #include "macro.h"
10 #include "config.h"
11 #include "gemini.h"
12 #include "page.h"
13 #include "request.h"
14 #define ABOUT_INTERNAL
15 #include "about.h"
16 #include "error.h"
17 #include "strlcpy.h"
18 #include "memory.h"
19 #include "sandbox.h"
20 #include "parser.h"
21 #include "utf8.h"
22
23 char help_page[] =
24 HEADER \
25 "# Help\n\n" \
26 HELP_INFO;
27
28 char about_page[] =
29 HEADER \
30 "# List of \"about\" pages\n\n" \
31 "=>about:about\n" \
32 "=>about:blank\n" \
33 "=>about:bookmarks\n" \
34 "=>about:certificates\n" \
35 "=>about:config\n" \
36 "=>about:help\n" \
37 "=>about:history\n" \
38 "=>about:known-hosts\n" \
39 "=>about:license\n" \
40 "=>about:newtab\n" \
41 "=>about:sandbox\n";
42
43 char license_page[] =
44 HEADER \
45 "# Vgmi license\n\n" \
46 "Copyright (c) 2024 RMF <rawmonk@rmf-dev.com>\n\n" \
47 "Permission to use, copy, modify, and distribute this software for any\n" \
48 "purpose with or without fee is hereby granted, provided that the above\n" \
49 "copyright notice and this permission notice appear in all copies.\n\n" \
50 "THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n" \
51 "WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n" \
52 "MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n" \
53 "ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n" \
54 "WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n" \
55 "ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n" \
56 "OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n";
57
58 char sandbox_page[] =
59 HEADER \
60 "# Sandbox information\n\n" \
61 ""SANDBOX_INFO"\n" \
62 "Filesystem access\t: "SANDBOX_FILESYSTEM"\n" \
63 "IPC access\t\t\t: "SANDBOX_IPC"\n" \
64 "Devices access\t\t: "SANDBOX_DEVICE"\n" \
65 "Parser isolation\t: "SANDBOX_PARSER"\n";
66
67 char sandbox_disabled_page[] =
68 HEADER \
69 "# Sandbox information\n\n" \
70 "The sandbox is disabled, enable it in about:config.\n" \
71 "Filesystem access\t: Unrestricted\n" \
72 "IPC access\t\t\t: Unrestricted\n" \
73 "Devices access\t\t: Unrestricted\n" \
74 "Parser isolation\t: Unrestricted\n";
75
76 void *dyn_utf8_strcat(char *dst, size_t *dst_length,
77 const char *src, size_t src_len) {
78 const size_t sum = (dst ? *dst_length : 0) + src_len + 2;
79 void *ptr = realloc(dst, sum + 1);
80 size_t start;
81 if (!ptr) return NULL;
82 dst = ptr;
83 start = *dst_length ? utf8_len(dst, *dst_length) : 0;
84 utf8_cpy(&dst[start], src, sum - start);
85 *dst_length = utf8_len(dst, sum);
86 return dst;
87 }
88
89 void *dyn_strcat(char *dst, size_t *dst_length,
90 const char *src, size_t src_len) {
91 const size_t sum = (dst ? *dst_length : 0) + src_len + 2;
92 void *ptr = realloc(dst, sum + 1);
93 if (!ptr) return NULL;
94 dst = ptr;
95 strlcpy(&dst[*dst_length ? strnlen(dst, *dst_length) : 0], src, sum);
96 *dst_length = strnlen(dst, sum);
97 return dst;
98 }
99
100 static int parse_data_status(struct request *request,
101 char *data, size_t len, int status) {
102 if (readonly(data, len, &request->data)) return ERROR_MEMORY_FAILURE;
103 request->status = status;
104 request->length = len;
105 free(data);
106 return parse_request(NULL, request);
107 }
108
109 static int parse_data(struct request *request, char *data, size_t len) {
110 return parse_data_status(request, data, len, GMI_SUCCESS);
111 }
112
113 static int static_page(struct request *request, const char *data, size_t len) {
114 if (readonly(data, len, &request->data)) return ERROR_MEMORY_FAILURE;
115 request->status = GMI_SUCCESS;
116 request->length = len - 1;
117 return parse_request(NULL, request);
118 }
119
120 int about_parse(struct request *request) {
121
122 char param[MAX_URL];
123 char *ptr = strchr(request->url, '/');
124 char *data;
125 size_t length;
126 int ret;
127
128 if (ptr) {
129 *ptr = 0;
130 ptr++;
131 STRLCPY(param, ptr);
132 } else param[0] = 0;
133 if (!strcmp(request->url, "about:about")) {
134 return static_page(request, V(about_page));
135 }
136 if (!strcmp(request->url, "about:blank")) {
137 request->status = GMI_SUCCESS;
138 STRLCPY(request->page.title, "about:blank");
139 return 0;
140 }
141 if (!strcmp(request->url, "about:bookmarks")) {
142 if (ptr && (ret = about_bookmarks_param(param))) return ret;
143 if ((ret = about_bookmarks(&data, &length))) return ret;
144 return parse_data(request, data, length);
145 }
146 if (!strcmp(request->url, "about:certificates")) {
147 if (ptr && (ret = about_certificates_param(param))) return ret;
148 if ((ret = about_certificates(&data, &length))) return ret;
149 return parse_data(request, data, length);
150 }
151 if (!strcmp(request->url, "about:help")) {
152 return static_page(request, V(help_page));
153 }
154 if (!strcmp(request->url, "about:license")) {
155 return static_page(request, V(license_page));
156 }
157 if (!strcmp(request->url, "about:newtab")) {
158 if ((ret = about_newtab(&data, &length))) return ret;
159 return parse_data(request, data, length);
160 }
161 if (!strcmp(request->url, "about:known-hosts")) {
162 if (ptr && (ret = about_known_hosts_arg(param))) return ret;
163 if ((ret = about_known_hosts(&data, &length))) return ret;
164 return parse_data(request, data, length);
165 }
166 if (!strcmp(request->url, "about:config")) {
167 int query = ptr ? (strchr(param, '?') != NULL) : 0;
168 ret = ptr ? about_config_arg(param, &data, &length) :
169 about_config(&data, &length);
170 if (ret) return ret;
171 if (ptr) {
172 int len = strnlen(V(request->url));
173 if (len + strnlen(V(param)) + 1 > sizeof(request->url))
174 return ERROR_INVALID_ARGUMENT;
175 request->url[len] = '/';
176 strlcpy(&request->url[len + 1], param,
177 sizeof(request->url) - len - 1);
178 }
179 /* reset url on succesful query */
180 if (query) STRLCPY(request->url, "about:config");
181 return parse_data_status(request, data, length - 1,
182 ptr ? GMI_INPUT : GMI_SUCCESS);
183 }
184 if (!strcmp(request->url, "about:history")) {
185 if (ptr && (ret = about_history_param(param))) return ret;
186 if ((ret = about_history(&data, &length))) return ret;
187 return parse_data(request, data, length - 1);
188 }
189 if (!strcmp(request->url, "about:sandbox")) {
190 if (!config.enableSandbox) {
191 return static_page(request, V(sandbox_disabled_page));
192 }
193 return static_page(request, V(sandbox_page));
194 }
195 return ERROR_INVALID_URL;
196 }
197