💾 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

View Raw

More Information

-=-=-=-=-=-=-

Go Back

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