Skip to content

Commit

Permalink
fix: escape all file URLs to support all kind of special chars
Browse files Browse the repository at this point in the history
Signed-off-by: Stefan Dej <[email protected]>
  • Loading branch information
meteyou committed Dec 3, 2024
1 parent 6011887 commit fb92abc
Show file tree
Hide file tree
Showing 12 changed files with 40 additions and 34 deletions.
4 changes: 2 additions & 2 deletions src/components/gcodeviewer/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ import { Component, Mixins, Prop, Ref, Watch } from 'vue-property-decorator'
import BaseMixin from '../mixins/base'
import GCodeViewer from '@sindarius/gcodeviewer'
import axios, { AxiosProgressEvent } from 'axios'
import { formatFilesize } from '@/plugins/helpers'
import { escapePath, formatFilesize } from '@/plugins/helpers'
import Panel from '@/components/ui/Panel.vue'
import CodeStream from '@/components/gcodeviewer/CodeStream.vue'
import {
Expand Down Expand Up @@ -630,7 +630,7 @@ export default class Viewer extends Mixins(BaseMixin) {
const CancelToken = axios.CancelToken
this.downloadSnackbar.cancelTokenSource = CancelToken.source()
const text = await axios
.get(this.apiUrl + '/server/files/' + encodeURI(filename), {
.get(this.apiUrl + '/server/files/' + escapePath(filename), {
cancelToken: this.downloadSnackbar.cancelTokenSource.token,
responseType: 'blob',
onDownloadProgress: (progressEvent: AxiosProgressEvent) => {
Expand Down
6 changes: 3 additions & 3 deletions src/components/panels/GcodefilesPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@
import { Component, Mixins, Watch } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
import { defaultBigThumbnailBackground, validGcodeExtensions } from '@/store/variables'
import { formatFilesize, formatPrintTime, sortFiles } from '@/plugins/helpers'
import { escapePath, formatFilesize, formatPrintTime, sortFiles } from '@/plugins/helpers'
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
import Panel from '@/components/ui/Panel.vue'
import SettingsRow from '@/components/settings/SettingsRow.vue'
Expand Down Expand Up @@ -1258,7 +1258,7 @@ export default class GcodefilesPanel extends Mixins(BaseMixin, ControlMixin) {
downloadFile() {
const filename = this.currentPath + '/' + this.contextMenu.item.filename
const href = this.apiUrl + '/server/files/gcodes' + encodeURI(filename)
const href = this.apiUrl + '/server/files/gcodes' + escapePath(filename)
window.open(href)
}
Expand All @@ -1268,7 +1268,7 @@ export default class GcodefilesPanel extends Mixins(BaseMixin, ControlMixin) {
const addElementToItems = async (absolutPath: string, directory: FileStateFile[]) => {
for (const file of directory) {
const filePath = `${absolutPath}/${file.filename}`
const filePath = `${absolutPath}/${escapePath(file.filename)}`
if (file.isDirectory && file.childrens) {
await addElementToItems(filePath, file.childrens)
Expand Down
4 changes: 2 additions & 2 deletions src/components/panels/History/HistoryListEntryJob.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ import {
mdiPrinter,
mdiTextBoxSearch,
} from '@mdi/js'
import { formatFilesize, formatPrintTime } from '@/plugins/helpers'
import { escapePath, formatFilesize, formatPrintTime } from '@/plugins/helpers'
import { HistoryListPanelCol } from '@/components/panels/HistoryListPanel.vue'
import HistoryListPanelNoteDialog from '@/components/dialogs/HistoryListPanelNoteDialog.vue'
import AddBatchToQueueDialog from '@/components/dialogs/AddBatchToQueueDialog.vue'
Expand Down Expand Up @@ -321,7 +321,7 @@ export default class HistoryListPanel extends Mixins(BaseMixin) {
relative_url = this.item.filename.substring(0, this.item.filename.lastIndexOf('/') + 1)
}
return `${this.apiUrl}/server/files/gcodes/${encodeURI(relative_url + thumbnail.relative_path)}?timestamp=${
return `${this.apiUrl}/server/files/gcodes/${escapePath(relative_url + thumbnail.relative_path)}?timestamp=${
this.item.metadata.modified
}`
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/panels/Machine/ConfigFilesPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@
import { Component, Mixins } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
import ThemeMixin from '@/components/mixins/theme'
import { formatFilesize, sortFiles } from '@/plugins/helpers'
import { escapePath, formatFilesize, sortFiles } from '@/plugins/helpers'
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
import axios from 'axios'
import Panel from '@/components/ui/Panel.vue'
Expand Down Expand Up @@ -1033,7 +1033,7 @@ export default class ConfigFilesPanel extends Mixins(BaseMixin, ThemeMixin) {
downloadFile() {
const filename = this.absolutePath + '/' + this.contextMenu.item.filename
const href = `${this.apiUrl}/server/files${encodeURI(filename)}`
const href = `${this.apiUrl}/server/files${escapePath(filename)}`
window.open(href)
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/panels/Status/GcodefilesEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ import {
import Panel from '@/components/ui/Panel.vue'
import { defaultBigThumbnailBackground } from '@/store/variables'
import AddBatchToQueueDialog from '@/components/dialogs/AddBatchToQueueDialog.vue'
import { formatPrintTime } from '@/plugins/helpers'
import { escapePath, formatPrintTime } from '@/plugins/helpers'
@Component({
components: {
Expand Down Expand Up @@ -295,7 +295,7 @@ export default class StatusPanelGcodefilesEntry extends Mixins(BaseMixin, Contro
}
downloadFile() {
const href = this.apiUrl + '/server/files/gcodes/' + encodeURI(this.item.filename)
const href = this.apiUrl + '/server/files/gcodes/' + escapePath(this.item.filename)
window.open(href)
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/panels/Status/HistoryEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ import { mdiCloseThick, mdiDelete, mdiFile, mdiPlaylistPlus, mdiPrinter } from '
import { defaultBigThumbnailBackground, thumbnailBigMin, thumbnailSmallMax, thumbnailSmallMin } from '@/store/variables'
import { ServerHistoryStateJobWithCount } from '@/store/server/history/types'
import { FileStateFileThumbnail } from '@/store/files/types'
import { formatPrintTime } from '@/plugins/helpers'
import { escapePath, formatPrintTime } from '@/plugins/helpers'
@Component
export default class StatusPanelHistoryEntry extends Mixins(BaseMixin) {
mdiCloseThick = mdiCloseThick
Expand Down Expand Up @@ -250,7 +250,7 @@ export default class StatusPanelHistoryEntry extends Mixins(BaseMixin) {
relative_url = this.job.filename.substring(0, this.job.filename.lastIndexOf('/') + 1)
}
return `${this.apiUrl}/server/files/gcodes/${encodeURI(relative_url + thumbnail.relative_path)}?timestamp=${
return `${this.apiUrl}/server/files/gcodes/${escapePath(relative_url + thumbnail.relative_path)}?timestamp=${
this.job.metadata.modified
}`
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/panels/Status/PrintstatusThumbnail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import BaseMixin from '@/components/mixins/base'
import { defaultBigThumbnailBackground, thumbnailBigMin, thumbnailSmallMax, thumbnailSmallMin } from '@/store/variables'
import { mdiFileOutline, mdiFile } from '@mdi/js'
import { Debounce } from 'vue-debounce-decorator'
import { escapePath } from '@/plugins/helpers'
@Component({})
export default class StatusPanelPrintstatusThumbnail extends Mixins(BaseMixin) {
Expand Down Expand Up @@ -119,7 +120,7 @@ export default class StatusPanelPrintstatusThumbnail extends Mixins(BaseMixin) {
}
if (thumbnail && 'relative_path' in thumbnail) {
return `${this.apiUrl}/server/files/gcodes/${encodeURI(
return `${this.apiUrl}/server/files/gcodes/${escapePath(
relative_url + thumbnail.relative_path
)}?timestamp=${this.current_file.modified}`
}
Expand Down Expand Up @@ -170,7 +171,7 @@ export default class StatusPanelPrintstatusThumbnail extends Mixins(BaseMixin) {
}
if (thumbnail && 'relative_path' in thumbnail) {
return `${this.apiUrl}/server/files/gcodes/${encodeURI(
return `${this.apiUrl}/server/files/gcodes/${escapePath(
relative_url + thumbnail.relative_path
)}?timestamp=${this.current_file.modified}`
}
Expand Down
8 changes: 4 additions & 4 deletions src/components/panels/Timelapse/TimelapseFilesPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@
<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
import { formatFilesize, sortFiles } from '@/plugins/helpers'
import { escapePath, formatFilesize, sortFiles } from '@/plugins/helpers'
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
import Panel from '@/components/ui/Panel.vue'
import PathNavigation from '@/components/ui/PathNavigation.vue'
Expand Down Expand Up @@ -678,7 +678,7 @@ export default class TimelapseFilesPanel extends Mixins(BaseMixin) {
const filename = item.filename.slice(0, item.filename.lastIndexOf('.'))
const preview = this.files?.find((file) => file.filename === filename + '.jpg')
if (preview) {
return `${this.apiUrl}/server/files/${encodeURI(this.currentPath)}/${encodeURI(
return `${this.apiUrl}/server/files/${escapePath(this.currentPath)}/${escapePath(
preview.filename
)}?timestamp=${preview.modified.getTime()}`
}
Expand All @@ -694,7 +694,7 @@ export default class TimelapseFilesPanel extends Mixins(BaseMixin) {
else if (item.filename.endsWith('zip')) {
this.downloadFile(item.filename)
} else if (item.filename.endsWith('mp4')) {
this.videoDialogFilename = encodeURI(`${this.currentPath}/${item.filename}`)
this.videoDialogFilename = escapePath(`${this.currentPath}/${item.filename}`)
this.boolVideoDialog = true
}
}
Expand Down Expand Up @@ -730,7 +730,7 @@ export default class TimelapseFilesPanel extends Mixins(BaseMixin) {
downloadFile(filename: string) {
const path = this.currentPath + '/' + filename
const href = this.apiUrl + '/server/files/' + encodeURI(path)
const href = this.apiUrl + '/server/files/' + escapePath(path)
window.open(href)
}
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,10 @@ export function sortResolutions(a: string, b: string) {

return aSplit - bSplit
}

export function escapePath(path: string): string {
return path
.split('/')
.map((part) => encodeURIComponent(part))
.join('/')
}
4 changes: 2 additions & 2 deletions src/store/editor/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import axios from 'axios'
import { sha256 } from 'js-sha256'
import Vue from 'vue'
import i18n from '@/plugins/i18n'
import { windowBeforeUnloadFunction } from '@/plugins/helpers'
import { escapePath, windowBeforeUnloadFunction } from '@/plugins/helpers'

export const actions: ActionTree<EditorState, RootState> = {
reset({ commit }) {
Expand Down Expand Up @@ -52,7 +52,7 @@ export const actions: ActionTree<EditorState, RootState> = {
fullFilepathArray.push(payload.filename)

const fullFilepath = fullFilepathArray.join('/')
const url = rootGetters['socket/getUrl'] + '/server/files/' + encodeURI(fullFilepath) + `?${Date.now()}`
const url = rootGetters['socket/getUrl'] + '/server/files/' + escapePath(fullFilepath) + `?${Date.now()}`

if (state.cancelToken) dispatch('cancelLoad')

Expand Down
15 changes: 6 additions & 9 deletions src/store/files/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { GetterTree } from 'vuex'
import { FileState, FileStateFile, FileStateGcodefile } from '@/store/files/types'
import { ServerHistoryStateJob } from '@/store/server/history/types'
import { escapePath } from '@/plugins/helpers'

// eslint-disable-next-line
export const getters: GetterTree<FileState, any> = {
Expand Down Expand Up @@ -50,7 +51,7 @@ export const getters: GetterTree<FileState, any> = {
let files: FileStateFile[] = []

if (path !== null) {
baseURL += encodeURI(path)
baseURL += escapePath(path)
const directory = getters['getDirectory']('gcodes' + path)
files = directory?.childrens ?? []
} else {
Expand Down Expand Up @@ -134,17 +135,13 @@ export const getters: GetterTree<FileState, any> = {
)

if (small_thumbnail && 'relative_path' in small_thumbnail) {
tmp.small_thumbnail = `${baseURL + subdirectory}/${encodeURI(
small_thumbnail.relative_path
)}?timestamp=${fileTimestamp}`
tmp.small_thumbnail = `${baseURL}${escapePath(subdirectory + '/' + small_thumbnail.relative_path)}?timestamp=${fileTimestamp}`
}

const big_thumbnail = file.thumbnails.find((thumb) => thumb.width >= thumbnailBigMin)

if (big_thumbnail && 'relative_path' in big_thumbnail) {
tmp.big_thumbnail = `${baseURL + subdirectory}/${encodeURI(
big_thumbnail.relative_path
)}?timestamp=${fileTimestamp}`
tmp.big_thumbnail = `${baseURL}${escapePath(subdirectory + '/' + big_thumbnail.relative_path)}?timestamp=${fileTimestamp}`

tmp.big_thumbnail_width = big_thumbnail.width
}
Expand Down Expand Up @@ -290,7 +287,7 @@ export const getters: GetterTree<FileState, any> = {
)

if (thumbnail && 'relative_path' in thumbnail) {
return `${rootGetters['socket/getUrl']}/server/files/${currentPath}/${encodeURI(
return `${rootGetters['socket/getUrl']}/server/files/${escapePath(currentPath)}/${escapePath(
thumbnail.relative_path
)}?timestamp=${item.modified.getTime()}`
}
Expand All @@ -304,7 +301,7 @@ export const getters: GetterTree<FileState, any> = {
const thumbnail = item.thumbnails.find((thumb) => thumb.width >= thumbnailBigMin)

if (thumbnail && 'relative_path' in thumbnail) {
return `${rootGetters['socket/getUrl']}/server/files/${encodeURI(currentPath)}/${encodeURI(
return `${rootGetters['socket/getUrl']}/server/files/${escapePath(currentPath)}/${escapePath(
thumbnail.relative_path
)}?timestamp=${item.modified.getTime()}`
}
Expand Down
9 changes: 5 additions & 4 deletions src/store/server/jobQueue/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { GetterTree } from 'vuex'
import { ServerJobQueueState, ServerJobQueueStateJob } from '@/store/server/jobQueue/types'
import Vue from 'vue'
import { thumbnailBigMin, thumbnailSmallMax, thumbnailSmallMin } from '@/store/variables'
import { escapePath } from '@/plugins/helpers'

// eslint-disable-next-line
export const getters: GetterTree<ServerJobQueueState, any> = {
Expand Down Expand Up @@ -50,9 +51,9 @@ export const getters: GetterTree<ServerJobQueueState, any> = {
return (
rootGetters['socket/getUrl'] +
'/server/files/' +
path +
escapePath(path) +
'/' +
encodeURI(thumbnail.relative_path) +
escapePath(thumbnail.relative_path) +
'?timestamp=' +
item.metadata?.modified.getTime()
)
Expand All @@ -73,9 +74,9 @@ export const getters: GetterTree<ServerJobQueueState, any> = {
return (
rootGetters['socket/getUrl'] +
'/server/files/' +
path +
escapePath(path) +
'/' +
encodeURI(thumbnail.relative_path) +
escapePath(thumbnail.relative_path) +
'?timestamp=' +
item.metadata?.modified.getTime()
)
Expand Down

0 comments on commit fb92abc

Please sign in to comment.