comparison mrjunejune/test/latex_renderer_test.c @ 244:b8aa08503378

[tools] Add sandboxed online LaTeX editor Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Mon, 03 Aug 2026 16:56:25 -0700
parents
children 70f2a3dafc1c
comparison
equal deleted inserted replaced
243:823f2a8b16c8 244:b8aa08503378
1 #include "mrjunejune/latex_renderer.h"
2
3 #include <assert.h>
4 #include <dirent.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <unistd.h>
8
9 static size_t latex_workspace_count(void)
10 {
11 DIR *directory = opendir("/tmp");
12 assert(directory);
13 size_t count = 0;
14 struct dirent *entry;
15 while ((entry = readdir(directory)) != NULL)
16 {
17 if (strncmp(entry->d_name, "mrjunejune-latex-", 19) == 0)
18 count++;
19 }
20 closedir(directory);
21 return count;
22 }
23
24 int main(void)
25 {
26 size_t initial_workspaces = latex_workspace_count();
27
28 const char *valid =
29 "\\documentclass{article}\n"
30 "\\begin{document}\n"
31 "Hello from the sandbox. $x^2 + y^2 = z^2$\n"
32 "\\end{document}\n";
33 Latex_Render_Result result = Latex_Render(
34 (const uint8_t *)valid,
35 strlen(valid));
36 if (result.status != LATEX_RENDER_OK)
37 fprintf(stderr, "%s\n", result.diagnostics ? result.diagnostics : "unknown error");
38 assert(result.status == LATEX_RENDER_OK);
39 assert(result.pdf_size > 1000);
40 assert(memcmp(result.pdf_data, "%PDF-", 5) == 0);
41 Latex_Render_Result_Destroy(&result);
42
43 const char *invalid =
44 "\\documentclass{article}\n"
45 "\\begin{document}\n"
46 "\\notarealcommand\n"
47 "\\end{document}\n";
48 result = Latex_Render((const uint8_t *)invalid, strlen(invalid));
49 assert(result.status == LATEX_RENDER_COMPILE_ERROR);
50 assert(result.diagnostics);
51 assert(strstr(result.diagnostics, "Undefined control sequence"));
52 Latex_Render_Result_Destroy(&result);
53
54 const char *host_read =
55 "\\documentclass{article}\n"
56 "\\begin{document}\n"
57 "\\input{/etc/passwd}\n"
58 "\\end{document}\n";
59 result = Latex_Render((const uint8_t *)host_read, strlen(host_read));
60 assert(result.status == LATEX_RENDER_COMPILE_ERROR);
61 assert(result.diagnostics);
62 assert(!strstr(result.diagnostics, "root:x:"));
63 Latex_Render_Result_Destroy(&result);
64
65 char shell_path[128];
66 snprintf(
67 shell_path,
68 sizeof(shell_path),
69 "/tmp/mrjunejune-latex-shell-%ld",
70 (long)getpid());
71 char shell_escape[512];
72 snprintf(
73 shell_escape,
74 sizeof(shell_escape),
75 "\\documentclass{article}\n"
76 "\\begin{document}\n"
77 "\\immediate\\write18{touch %s}\n"
78 "Shell escape must stay disabled.\n"
79 "\\end{document}\n",
80 shell_path);
81 result = Latex_Render(
82 (const uint8_t *)shell_escape,
83 strlen(shell_escape));
84 assert(result.status == LATEX_RENDER_OK);
85 assert(access(shell_path, F_OK) != 0);
86 Latex_Render_Result_Destroy(&result);
87
88 uint8_t oversized[LATEX_SOURCE_MAX_BYTES + 1] = {0};
89 memset(oversized, 'x', sizeof(oversized));
90 result = Latex_Render(oversized, sizeof(oversized));
91 assert(result.status == LATEX_RENDER_INVALID_INPUT);
92 Latex_Render_Result_Destroy(&result);
93
94 const char *infinite =
95 "\\documentclass{article}\n"
96 "\\begin{document}\n"
97 "\\loop\\iftrue\\repeat\n"
98 "\\end{document}\n";
99 result = Latex_Render((const uint8_t *)infinite, strlen(infinite));
100 assert(result.status == LATEX_RENDER_TIMEOUT);
101 Latex_Render_Result_Destroy(&result);
102
103 assert(latex_workspace_count() == initial_workspaces);
104 return 0;
105 }