GAS でアップロードし、GoogleDrive に保存した画像ファイルが破損?!


なんか画像ファイルが壊れてるっぽいんです

 以下のようなGASプロジェクトで、スマホからカメラで撮影した画像ファイルを、GoogleDriveに保存させていたのですが、2020年2月下旬あたりから、アップロードされている画像ファイルが閲覧できないことに気づきました。

upload.html
<form action="" enctype="multipart/form-data" id="photoForm">
  <input type="hidden" name="photoBarcode" id="photoBarcode"/>
  <input type="file" accept="image/*" capture="environment" name="photo" id="photo" onClick="$('#photo').val('')" onchange="cameraSend($('#photoForm').get(0))" style="display:none;"/>
</form>
camera.js
function cameraSend(data){
  google.script.run.withSuccessHandler(cameraFinish).withFailureHandler(cameraError).recievePhoto(data);
}
GAS
function recievePhoto(data){
  if(data && data.photo){
    var file = DriveApp.getFolderById('XXXXXXXXXXXX').createFile(data.photo);
    file.setName(data.name + '.jpg');
  }
}

ファイルはできていて、ファイル名もちゃんと登録されているけど、ファイルは開けない

GoogleDriveは、通常、ファイルをシングルクリックすると、プレビューが表示されるんですが、このファイルはプレビューも表示されず、GIMPでファイルとして開くと、以下のような感じ

結論

 Chrome V8 を搭載した新しい Apps Script ランタイムを無効化する
 こいつがバグがあるみたいです。

 設定したら、公開するのを忘れないでね。

以下、私の右往左往をご覧になりたい方は読み進めてください。

バイナリエディタで見てみよう

 毎度お世話になります。バイナリエディタ BZ です。

 ※あっ、スマホの機種バレ・・・古いの使って何が悪いっ!

 Exif という文字は見えますから、なんとかJPEGファイルでアップロードされようとしている様子はうかがえますが、本来JPEGのバイナリ配列は、ffd8 から始まって、 ffd9 で終わっているはずですね。
 このルールに反しています。
 @kazuaki0213さんの記事「JPEG画像の中をちょっとだけのぞいてみる」より
 ※いつもありがとうございます

 なんだか、先頭もそうですが、 EF BF BD というのがそそかしこに出てきますね。
 これ検索すると、Chrome がダウンロードしようとしたときに、勝手にUTF-8にエンコードしようとして、バイナリファイルに混ぜ込んでいるとか、そういう記事を見つけました。

別ブラウザから行けるのか?

 Edge から操作しても、同様でした。
 やはり EF BF BD が大量に入り込んでいます。

じゃ、GAS側かっ!

 はい。犯人が割れました。
 これですっ!
 そういえば、2月頃に、こんなメッセージが表示されるようになっていましたね。

 そうです。私はなんのためらいもなく、これを有効にしていました。

原因と得られたこと

  • Chrome Engine のバグらしい
  • GAS側のJavascript は Chrome Engin で動作しているらしい
  • GAS側がクライアントからダウンロード(言葉合ってる?)するときに、UTF-8 で解釈しようとしているらしい
  • 2020/4/17 現在、このバグはまだ治っていないらしい
  • 画像が開けなかったら、バイナリエディタで覗いてみると、答えにたどり着けることがあるらしい(これ基本です?)