File tree Expand file tree Collapse file tree 4 files changed +42
-6
lines changed
frontend/frame-editors/latex-editor Expand file tree Collapse file tree 4 files changed +42
-6
lines changed Original file line number Diff line number Diff line change @@ -50,6 +50,7 @@ import { once } from "@cocalc/util/async-utils";
5050import { ExecOutput } from "@cocalc/util/db-schema/projects" ;
5151import {
5252 change_filename_extension ,
53+ is_bad_latex_filename ,
5354 path_split ,
5455 separate_file_extension ,
5556 sha1 ,
@@ -238,9 +239,10 @@ export class Actions extends BaseActions<LatexEditorState> {
238239
239240 private init_bad_filename ( ) : void {
240241 // #3230 two or more spaces
242+ // Shell injection prevention: single quotes break bash string interpolation
241243 // note: if there are additional reasons why a filename is bad, add it to the
242244 // alert msg in run_build.
243- this . bad_filename = / \s \s + / . test ( this . path ) ;
245+ this . bad_filename = is_bad_latex_filename ( this . path ) ;
244246 }
245247
246248 private init_ext_filename ( ) : void {
@@ -878,7 +880,7 @@ export class Actions extends BaseActions<LatexEditorState> {
878880
879881 if ( this . bad_filename ) {
880882 const err = `ERROR: It is not possible to compile this LaTeX file with the name '${ this . path } '.
881- Please modify the filename, such that it does **not** contain two or more consecutive spaces.` ;
883+ Please modify the filename, such that it does **not** contain two or more consecutive spaces or single quotes (') .` ;
882884 this . set_error ( err ) ;
883885 return ;
884886 }
Original file line number Diff line number Diff line change 11/*
2- * This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
2+ * This file is part of CoCalc: Copyright © 2020-2025 Sagemath, Inc.
33 * License: MS-RSL – see LICENSE.md for details
44 */
55
@@ -33,18 +33,26 @@ export async function sagetex_hash(
3333 const { base, directory } = parse_path ( path ) ; // base, directory, filename
3434 const s = sagetex_file ( base ) ;
3535 status ( `sha1sum ${ s } ` ) ;
36+
37+ // Check if file exists and compute hash only if it does; otherwise return unique value
3638 const output = await exec (
3739 {
3840 timeout : 10 ,
39- command : " sha1sum" ,
40- args : [ s ] ,
41+ command : `test -f ' ${ s } ' && sha1sum ' ${ s } ' || true` ,
42+ bash : true ,
4143 project_id : project_id ,
4244 path : output_directory || directory ,
43- err_on_exit : true ,
45+ err_on_exit : false ,
4446 aggregate : time ,
4547 } ,
4648 path ,
4749 ) ;
50+
51+ // If file doesn't exist, return unique timestamp-based value to ensure rebuild
52+ if ( ! output . stdout . trim ( ) ) {
53+ return `missing-${ Date . now ( ) } ` ;
54+ }
55+
4856 return output . stdout . split ( " " ) [ 0 ] ;
4957}
5058
Original file line number Diff line number Diff line change @@ -160,6 +160,24 @@ test("EDITOR_PREFIX", () => {
160160 expect ( misc . EDITOR_PREFIX ) . toBe ( "editor-" ) ;
161161} ) ;
162162
163+ describe ( "is_bad_latex_filename" , ( ) => {
164+ test ( "allows filenames without double spaces or quotes" , ( ) => {
165+ expect ( misc . is_bad_latex_filename ( "paper.tex" ) ) . toBe ( false ) ;
166+ expect ( misc . is_bad_latex_filename ( "my paper.tex" ) ) . toBe ( false ) ;
167+ expect ( misc . is_bad_latex_filename ( "folder/subfolder/file.tex" ) ) . toBe ( false ) ;
168+ } ) ;
169+
170+ test ( "rejects filenames with double spaces" , ( ) => {
171+ expect ( misc . is_bad_latex_filename ( "my paper.tex" ) ) . toBe ( true ) ;
172+ expect ( misc . is_bad_latex_filename ( "folder/bad name/file.tex" ) ) . toBe ( true ) ;
173+ } ) ;
174+
175+ test ( "rejects filenames with single quotes" , ( ) => {
176+ expect ( misc . is_bad_latex_filename ( "author's-notes.tex" ) ) . toBe ( true ) ;
177+ expect ( misc . is_bad_latex_filename ( "folder/author's-notes.tex" ) ) . toBe ( true ) ;
178+ } ) ;
179+ } ) ;
180+
163181describe ( "test code for displaying numbers as currency with 2 or sometimes 3 decimals of precision" , ( ) => {
164182 const { currency } = misc ;
165183 it ( "displays 1.23" , ( ) => {
Original file line number Diff line number Diff line change @@ -160,6 +160,14 @@ export function change_filename_extension(
160160 return `${ name } .${ new_ext } ` ;
161161}
162162
163+ // Check if a filename contains characters that are problematic for LaTeX compilation.
164+ // Returns true if the filename contains:
165+ // - Two or more consecutive spaces (breaks LaTeX processing, see #3230)
166+ // - Single quotes (breaks bash string interpolation in build commands)
167+ export function is_bad_latex_filename ( path : string ) : boolean {
168+ return / \s \s + | ' / . test ( path ) ;
169+ }
170+
163171// Takes parts to a path and intelligently merges them on '/'.
164172// Continuous non-'/' portions of each part will have at most
165173// one '/' on either side.
You can’t perform that action at this time.
0 commit comments