Update: I created an issue: https://issuetracker.google.com/issues/150675170
My web app worked well for a long time, but now suddenly the uploaded pdf files become corrupted. Below is a small reduced example that can be used to reproduce the issue.
Looking at the uploaded file content, it looks like the file content is treated as text, and several characters are replaced with EF BF BD
, which is the UTF-8 byte sequence for 'REPLACEMENT CHARACTER' (U+FFFD).
For example, first bytes of the original PDF file:
25 50 44 46 2D 31 2E 34 0A 25 E2 E3 CF D3 0A 31 39 | %PDF-1.4
%a??ó
19
It got uploaded as:
25 50 44 46 2D 31 2E 34 0A 25 EF BF BD EF BF BD EF BF BD EF BF BD 0A 31 39 | %PDF-1.4
%????????????
19
I'm not sure where to report it, I only hope that a Google employee will see it and fix it.
In the meanwhile, perhaps somebody familiar with Google Apps Script has an idea for a workaround.
Below is the small reduced example - deploy, upload a binary file, go to Drive, find it under the "test" folder, download it, observe that it's broken.
HTML template, file name test_form.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form id="test-form">
<input type="file" id="test-file" name="test-file">
<button id="submit-button" type="submit">Upload</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
(function () {
'use strict';
$('#test-form').submit(function (e) {
e.preventDefault(); // prevent form from submitting
google.script.run
.withFailureHandler(fileUploadedFailure)
.withSuccessHandler(fileUploaded)
.uploadFilesFrame(this);
});
function fileUploaded(status) {
alert(status);
}
function fileUploadedFailure(error) {
alert('Failed: ' + error.message);
}
})();
</script>
</body>
</html>
Server code, file name Code.gs
:
var rootFolderName = "test";
function doGet(e) {
var template = HtmlService.createTemplateFromFile('test_form');
return template.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function uploadFilesFrame(form) {
try {
var fileBlob = form['test-file'];
var rootFolder = DriveApp.getFoldersByName(rootFolderName);
if (rootFolder.hasNext()) {
rootFolder = rootFolder.next();
} else {
rootFolder = DriveApp.createFolder(rootFolderName);
}
var file = rootFolder.createFile(fileBlob);
return JSON.stringify({"status": 'ok', "msg": file.getId()});
} catch (error) {
return JSON.stringify({"status": 'error', "data": error.stack});
}
}
See Question&Answers more detail:
os