Mercurial
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrjunejune/test/latex_renderer_test.c Mon Aug 03 16:56:25 2026 -0700 @@ -0,0 +1,105 @@ +#include "mrjunejune/latex_renderer.h" + +#include <assert.h> +#include <dirent.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static size_t latex_workspace_count(void) +{ + DIR *directory = opendir("/tmp"); + assert(directory); + size_t count = 0; + struct dirent *entry; + while ((entry = readdir(directory)) != NULL) + { + if (strncmp(entry->d_name, "mrjunejune-latex-", 19) == 0) + count++; + } + closedir(directory); + return count; +} + +int main(void) +{ + size_t initial_workspaces = latex_workspace_count(); + + const char *valid = + "\\documentclass{article}\n" + "\\begin{document}\n" + "Hello from the sandbox. $x^2 + y^2 = z^2$\n" + "\\end{document}\n"; + Latex_Render_Result result = Latex_Render( + (const uint8_t *)valid, + strlen(valid)); + if (result.status != LATEX_RENDER_OK) + fprintf(stderr, "%s\n", result.diagnostics ? result.diagnostics : "unknown error"); + assert(result.status == LATEX_RENDER_OK); + assert(result.pdf_size > 1000); + assert(memcmp(result.pdf_data, "%PDF-", 5) == 0); + Latex_Render_Result_Destroy(&result); + + const char *invalid = + "\\documentclass{article}\n" + "\\begin{document}\n" + "\\notarealcommand\n" + "\\end{document}\n"; + result = Latex_Render((const uint8_t *)invalid, strlen(invalid)); + assert(result.status == LATEX_RENDER_COMPILE_ERROR); + assert(result.diagnostics); + assert(strstr(result.diagnostics, "Undefined control sequence")); + Latex_Render_Result_Destroy(&result); + + const char *host_read = + "\\documentclass{article}\n" + "\\begin{document}\n" + "\\input{/etc/passwd}\n" + "\\end{document}\n"; + result = Latex_Render((const uint8_t *)host_read, strlen(host_read)); + assert(result.status == LATEX_RENDER_COMPILE_ERROR); + assert(result.diagnostics); + assert(!strstr(result.diagnostics, "root:x:")); + Latex_Render_Result_Destroy(&result); + + char shell_path[128]; + snprintf( + shell_path, + sizeof(shell_path), + "/tmp/mrjunejune-latex-shell-%ld", + (long)getpid()); + char shell_escape[512]; + snprintf( + shell_escape, + sizeof(shell_escape), + "\\documentclass{article}\n" + "\\begin{document}\n" + "\\immediate\\write18{touch %s}\n" + "Shell escape must stay disabled.\n" + "\\end{document}\n", + shell_path); + result = Latex_Render( + (const uint8_t *)shell_escape, + strlen(shell_escape)); + assert(result.status == LATEX_RENDER_OK); + assert(access(shell_path, F_OK) != 0); + Latex_Render_Result_Destroy(&result); + + uint8_t oversized[LATEX_SOURCE_MAX_BYTES + 1] = {0}; + memset(oversized, 'x', sizeof(oversized)); + result = Latex_Render(oversized, sizeof(oversized)); + assert(result.status == LATEX_RENDER_INVALID_INPUT); + Latex_Render_Result_Destroy(&result); + + const char *infinite = + "\\documentclass{article}\n" + "\\begin{document}\n" + "\\loop\\iftrue\\repeat\n" + "\\end{document}\n"; + result = Latex_Render((const uint8_t *)infinite, strlen(infinite)); + assert(result.status == LATEX_RENDER_TIMEOUT); + Latex_Render_Result_Destroy(&result); + + assert(latex_workspace_count() == initial_workspaces); + return 0; +}