←back to thread

669 points danso | 3 comments | | HN request time: 0.633s | source
Show context
snazz ◴[] No.23261598[source]
Here's the relevant frontend source code for the file upload picker, if anyone's wondering (webpack://src/components/exam/submissions/FileInput.js):

  <input
            type="file"
            ref={inputRef}
            name="fileupload"
            disabled={disabled}
            accept={EXTENSIONS[type]}
            data-cb-element="no-cb"
            onChange={async e => {
              const [file] = Object.keys(e.target.files).map(key => e.target.files[key])
              const fileSizeInMb = file.size/(CONVERSION_BASE*CONVERSION_BASE)
              const fileSizeInKb = file.size/CONVERSION_BASE
              const split = file.name.split('.')
              const fileType = split[split.length-1].toLowerCase()
              const extensions = EXTENSIONS[type].split(', ')
              const isAllowedExtension = extensions.includes(`.${fileType}`)
              const alreadyExists = files.find(f => f.name === file.name && f.size === file.size && f.lastModified === file.lastModified)
              let error

              if (alreadyExists)
                error = { title: 'You have already uploaded a file with the same name.', details: 'Please attach a different file.' }
              else if (!isAllowedExtension)
                error = { title: 'This file type is not acceptable.', details: 'Please check the requirements, save your file in one of the accepted formats, and resubmit.' }
              else if (fileSizeInKb <= minSize)
                error = { title: 'Your file is too small.', details: 'Please check the file-size requirements, save a larger version, and resubmit.' }
              else if (fileSizeInMb > maxSize)
                error = { title: 'Your file is too big.', details: 'Please check the file-size requirements, save a smaller version, and resubmit. ' }
            
              if (error)
                await setError(<><strong>{error.title}</strong> {error.details}</>)
              else {
                await updateFiles(file)
                setError(null)
              }

              inputRef.current.value = null
            }}
          />
The EXTENSIONS variable is defined here:

  export const EXTENSIONS = {
    [TYPE_DOC]: '.txt, .doc, .docx, .pdf, .odt',
    [TYPE_PHOTO]: '.png, .jpg, .jpeg',
    [TYPE_AUDIO]: '.m4a, .mp3, .wav, .ogg'
  }
replies(4): >>23262022 #>>23262067 #>>23263420 #>>23266424 #
scott_s ◴[] No.23262067[source]
I'm trying to square this with the fact people pointed out downthread, which is that iPhones will automatically convert HEIC images to jpeg from an HTML input form. Perhaps it's the `isAllowedExtension` check? If `e.target.files` is the actual file names on disk (and not whatever temporary file the browser made out of the HEIC file), that would cause a problem.
replies(2): >>23262429 #>>23263533 #
acqq ◴[] No.23262429[source]
Apparently somebody claims to have been able to change the extension and submit the picture, but got "file corrupted" later:

"Senior Dave Spencer took a demo test before his Calculus AB exam to make sure he understood the process for uploading photos. He Airdropped an iPhone image of his responses to his Mac and tried to convert it by renaming the HEIC file to PNG. Changing a file’s extension does not guarantee that it will be converted, but Spencer was still able to submit the demo test with no problem.

Spencer used the same process on the real exam and thought it went through, but he received an email the next day saying the files were corrupted and that he needed to retake the test."

replies(3): >>23262587 #>>23262762 #>>23264041 #
1. scott_s ◴[] No.23262587[source]
That anecdote is inline with my explanation: the student manually changed the file extension on disk, then uploaded that. That would pass all of the checks, but it would still be in the wrong format, as manually changing the file extension does not cause a conversion to take place on disk, and that probably prevents the automatic conversion of HEIC to jpeg the iPhone itself does on such input fields.
replies(1): >>23265020 #
2. xxs ◴[] No.23265020[source]
all the checks - a proper check would be reading the contents and parsing the image.
replies(1): >>23271813 #
3. scott_s ◴[] No.23271813[source]
Yes, but that's not what the written code does.