Submissions: reject XML project files, show submitted file names to admin
This commit is contained in:
@@ -38,6 +38,14 @@ class SubmissionService(
|
||||
val last = submissions.findFirstByStudentIdAndLabIdOrderBySeqDesc(studentId, labId)
|
||||
val seq = (last?.seq ?: 0) + 1
|
||||
val payload = files.mapIndexed { i, f -> (f.originalFilename ?: "file$i") to f.bytes }
|
||||
payload.forEach { (name, bytes) ->
|
||||
if (looksLikeProjectFile(name, bytes)) {
|
||||
throw BadRequestException(
|
||||
"Файл «$name» похож на файл проекта (XML), а не на исходник. " +
|
||||
"Приложите файл .c/.h или zip с проектом.",
|
||||
)
|
||||
}
|
||||
}
|
||||
val stored = storage.store(studentId, labId, seq, payload)
|
||||
val entity = submissions.save(Submission(studentId = studentId, labId = labId, seq = seq))
|
||||
return toDto(entity, stored.files)
|
||||
@@ -70,6 +78,22 @@ class SubmissionService(
|
||||
return perStudent.values.map { toDto(it, filesOf(it)) }
|
||||
}
|
||||
|
||||
/** Файлы с "исходниковым" расширением, содержимое которых — XML-файл проекта (VS/IDE). */
|
||||
private val sourceExtensions = setOf("c", "h", "cpp", "hpp", "cc", "cxx", "txt")
|
||||
|
||||
private fun looksLikeProjectFile(name: String, bytes: ByteArray): Boolean {
|
||||
val ext = name.substringAfterLast('.', "").lowercase()
|
||||
if (ext !in sourceExtensions) return false
|
||||
val head = String(bytes, 0, minOf(bytes.size, 512), Charsets.UTF_8)
|
||||
.removePrefix("\uFEFF")
|
||||
.trimStart()
|
||||
.lowercase()
|
||||
return head.startsWith("<?xml") ||
|
||||
head.startsWith("<solution") ||
|
||||
head.startsWith("<project") ||
|
||||
head.startsWith("<configurations")
|
||||
}
|
||||
|
||||
private fun filesOf(s: Submission): List<String> =
|
||||
storage.listFiles(storage.dirFor(s.studentId, s.labId, s.seq))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user