SlideShare a Scribd company logo
JavaScript の世代間を埋めるパーツ -  過去と未来をつなぐ GIF89a - サイボウズ・ラボ株式会社 竹迫 良範 Real UNIX MAGAZINE Day (2007/11/03)
今日のお話
http://0xcc.net/misc/ggap.html  より Binary 2.0 Web 2.0 UNIX にみる世代間の断絶(高林さん説)
ハッカー世代間の感覚差(竹迫・説) 1950,60,70 年代 以前 Binary Hacks  世代 old type 、計算機の構造をきちんと理解、昔話好き 1980 年代 以降 Text Hacks  世代 ブラウザ ⇔ コンピュータ CPU 、アセンブリ言語 ⇔  JavaScript 画面出力(エスケープシーケンス) ⇔  HTML/CSS 外部記憶装置(仮想ドライバ) ⇔  Web サーバ( CGI ) 平成生まれ 理解の範囲を超える新人類 ケータイで親指プログラミング
凡人  - input device 109 key
old type hacker - input device 60 key
new type hacker - input device 12 key
next - input device ??? 0 key ?
マシン語を知らない子ども達
バイナリアン光成さんの話( LL Spirit にて)
Web のマシン語 || JavaScript
Shibuya.JS x John Resig
以上 前フリ 終了
 
本題
GIF89a (ハック)
HTML/CSS & JS & Perl in GIF89a (valid) Web Polyglot
Polyglot
5秒でわかる Polyglot (JavaScript in GIF89a) 正しい GIF 画像でもある JavaScript ファイル JavaScript として実行できる GIF 画像ファイル IE/Firefox/Opera/Safari できちんと動作 <script src=“alert0.gif” language=“JavaScript”>
Web Polyglot DEMO HTML/CSS & JS & Perl in GIF89a (valid)
View source
Perl in GIF89a GIF89a(q =/*.....Ä= );sub GIF89a{print &quot;Hello Perl!&quot;} __END__ #*/1);function GIF89a(){alert(&quot;Hello JavaScrpt!&quot;)} /*<body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>Hello HTML!</h1><!-- ................................................ ................................................ ................................................ ................................................ --><img src=?> <script src=# language=JavaScript></script></div>  */// ;
JavaScript in GIF89a GIF89a( q= /*.....Ä=);sub GIF89a{print &quot;Hello Perl!&quot;} __END__#*/ 1 );function GIF89a(){alert(&quot;Hello JavaScrpt!&quot;)} /*<body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>Hello HTML!</h1><!-- ................................................ ................................................ ................................................ ................................................ --><img src=?> <script src=# language=JavaScript></script></div>  */ // ;
HTML/CSS in GIF89a GIF89a(q=/*.....Ä=);sub GIF89a{print &quot;Hello Perl!&quot;} __END__#*/1);function GIF89a(){alert(&quot;Hello JavaScrpt!&quot;)} /* <body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>Hello HTML!</h1> <!-- ................................................ ................................................ ................................................ ................................................ --> <img src=?> <script src=# language=JavaScript></script> </div>  */// ;
How to break same-origin-policy. (Parallelize cross-domain access) Other GIF89a hacks GIF89a Binary Image Object for AJAX communications Protocol
従来:Ajaxでクロスドメイン通信する方法 1. XMLHttpRequest + Local proxy 非同期通信 API の元祖  XMLHttpRequest クロスドメイン通信ができないので  Local proxy パフォーマンスの問題(自サーバの Proxy 経由でアクセス) セキュリティの問題( Open Proxy 悪用の危険性) 2. Flash の力を借りる  + crossdomain.xml SocketJS  の実装など 3. <script src=“http://.../.js”> の動的生成 JSONP  で最近ブーム
JSONPの動作原理 function  callback (data) { // …  ここに処理を書く … } (1)コールバック関数の定義 (2) script tag  の動的生成 (3)サーバからのレスポンス クロスドメインで JavaScript 関数を実行 <script src=“http://example.com/data.json? jsonp= callback ” /> callback(  { foo: 'This is foo.',  bar: 'This is bar.',  moe: 'This is moe.' }  );
GIF89a でクロスドメイン通信 <img src=“null.gif?q=param&quot; onload=“ callback (this.width)&quot;> function  callback (data) { //… do action } (1) Define JS callback function (likes JSONP) (2) New Image Object CGI  にしても  OK http://example.com/webapi/null.gif?q=foobar 戻り値: GIF 画像の幅サイズ
画像ファイルのサイズ比較 画像サイズ  1x1 (モノクロ GIF ) 35 byte 画像サイズ  1000x1000 (モノクロ GIF )  1,735 byte 画像サイズ  1000x1000 ( 24bpp BMP ) 3,000,054 byte  (約 3MB ) 画像サイズ  65535x65535 ( 24bpp BMP ) 約 12GB ワークエリア足りません… orz
G I F (tm) Graphics Interchange Format (tm) A standard defining a mechanism for the storage and transmission of raster-based graphics information June 15, 1987 (c) CompuServe Incorporated, 1987 All rights reserved http://members.aol.com/royalef/gif87a.txt
GIF87a 仕様書 bits 7 6 5 4 3 2 1 0  Byte # +---------------+ |  |  1 +-Screen Width -+  Raster width in pixels (LSB first) |  |  2 +---------------+ |  |  3 +-Screen Height-+  Raster height in pixels (LSB first) |  |  4 +-+-----+-+-----+  M = 1, Global color map follows Descriptor |M|  cr |0|pixel|  5  cr+1 = # bits of color resolution +-+-----+-+-----+  pixel+1 = # bits/pixel in image |  background  |  6  background=Color index of screen background +---------------+  (color is defined from the Global color |0 0 0 0 0 0 0 0|  7  map or default map if none specified) +---------------+
任意の画像幅をできるだけ短く生成したい Image Block の存在しない GIF Header だけ 画像の幅と高さのサイズ情報をサーバで生成 最小で20byte固定長 sub create_gif { my ($width, $height) = @_; my $size = pack &quot;S2&quot;, $width, $height; return &quot;474946383761$sizef00000000000ffffff3b&quot;; } width と height の 16bit ずつ つまり 32bit の情報をサーバ側で GIF 形式にエンコードして渡せる Perl のサンプルコード
Firefox  ではサイズ情報を読めた!
しかし、 IE  では壊れた画像と認識 …  orz サイズ情報を読み出せない…
GRAPHICS INTERCHANGE FORMAT(sm) Version 89a (c)1987,1988,1989,1990 Copyright CompuServe Incorporated Columbus, Ohio http://www.w3.org/Graphics/GIF/spec-gif89a.txt
クロスブラウザ対策 GIF89aの形式にして 1x1のダミーの Image Block を挿入すると IEでも解釈するように http://www.tohoho-web.com/soft/wcnt.htm とほほの  WwwCounter  で使用されている GIF 画像連結ライブラリの動作原理にインスパイア 独立した一つの  Image Block
GIFファイルのデータ構造 +-----------------------+ | +-------------------+ | | |  GIF Signature  | | | +-------------------+ | | +-------------------+ | | | Screen Descriptor | | | +-------------------+ | | +-------------------+ | | | Global Color Map  | | | +-------------------+ | |-  GIF Terminator  -| +-----------------------+ +-----------------------+ | +-------------------+ | | |  GIF Signature  | |  5byte (GIF89a) | +-------------------+ | | +-------------------+ | | | Screen Descriptor | |  7 byte (width x height) | +-------------------+ | | +-------------------+ | | | Global Color Map  | | 6 byte (2 colors) | +-------------------+ | |  +-------------------+  | |  | IMAGE DESCRIPTOR  |  |  15 byte (1 x 1) |  +-------------------+  | |-  GIF Terminator  -|  1 byte (;) +-----------------------+ 20 byte 35 byte
return 16bit x 2 PerlでのGIF89a出力例(固定長35byte) #!/usr/bin/perl use strict; use warnings; sub create_gif { my $size = pack &quot;S2&quot;, @_; return &quot;GIF89a$sizef00000000000ffffff,&quot; . &quot;0000000001000100000202L0100;&quot;; } print &quot;Content-Length: 35&quot;; print &quot;Content-Type: image/gif&quot;; binmode(*STDOUT); print create_gif(65535, 65535); 1;
It works!
オールドタイプのためのC言語ライブラリ #include <stdio.h> #define print_gif_head() do { printf( &quot;Content-Length: 35&quot; &quot;Content-Type: image/gif&quot; &quot;&quot;); } while (0) #define print_gif_body(x,y) do { putchar('G'); putchar('I'); putchar('F'); putchar('8'); putchar('9'); putchar('a'); putchar(0xff & (x)); putchar(0xff & (x >> 8)); putchar(0xff & (y)); putchar(0xff & (y >> 8)); putchar(0xf0); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0xff); putchar(0xff); putchar(0xff); putchar(','); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x01); putchar(0x00); putchar(0x01); putchar(0x00); putchar(0x00); putchar(0x02); putchar(0x02); putchar('L'); putchar(0x01); putchar(0x00); putchar(';'); } while (0) int main() { print_gif_head(); print_gif_body(65535, 65535); }
 
!!
以上 GIF89a ハック 終了
歴史の古いGIF規格 GIF GIF87a(1987年) GIF89a(1989年) XML 規格化(1998年) JSON RFC4627(2006年) 20年前の データ交換 フォーマット コンピュータにやさしい バイナリアンにやさしい 地球にやさしい
温故知新
ご清聴ありがとうございました [ 宣伝 ]  サイボウズ・ラボでは人材募集中です

More Related Content

GIF89a Oldtype

  • 1. JavaScript の世代間を埋めるパーツ - 過去と未来をつなぐ GIF89a - サイボウズ・ラボ株式会社 竹迫 良範 Real UNIX MAGAZINE Day (2007/11/03)
  • 3. http://0xcc.net/misc/ggap.html  より Binary 2.0 Web 2.0 UNIX にみる世代間の断絶(高林さん説)
  • 4. ハッカー世代間の感覚差(竹迫・説) 1950,60,70 年代 以前 Binary Hacks 世代 old type 、計算機の構造をきちんと理解、昔話好き 1980 年代 以降 Text Hacks 世代 ブラウザ ⇔ コンピュータ CPU 、アセンブリ言語 ⇔ JavaScript 画面出力(エスケープシーケンス) ⇔ HTML/CSS 外部記憶装置(仮想ドライバ) ⇔ Web サーバ( CGI ) 平成生まれ 理解の範囲を超える新人類 ケータイで親指プログラミング
  • 5. 凡人 - input device 109 key
  • 6. old type hacker - input device 60 key
  • 7. new type hacker - input device 12 key
  • 8. next - input device ??? 0 key ?
  • 14.  
  • 17. HTML/CSS & JS & Perl in GIF89a (valid) Web Polyglot
  • 19. 5秒でわかる Polyglot (JavaScript in GIF89a) 正しい GIF 画像でもある JavaScript ファイル JavaScript として実行できる GIF 画像ファイル IE/Firefox/Opera/Safari できちんと動作 <script src=“alert0.gif” language=“JavaScript”>
  • 20. Web Polyglot DEMO HTML/CSS & JS & Perl in GIF89a (valid)
  • 22. Perl in GIF89a GIF89a(q =/*.....Ä= );sub GIF89a{print &quot;Hello Perl!&quot;} __END__ #*/1);function GIF89a(){alert(&quot;Hello JavaScrpt!&quot;)} /*<body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>Hello HTML!</h1><!-- ................................................ ................................................ ................................................ ................................................ --><img src=?> <script src=# language=JavaScript></script></div> */// ;
  • 23. JavaScript in GIF89a GIF89a( q= /*.....Ä=);sub GIF89a{print &quot;Hello Perl!&quot;} __END__#*/ 1 );function GIF89a(){alert(&quot;Hello JavaScrpt!&quot;)} /*<body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>Hello HTML!</h1><!-- ................................................ ................................................ ................................................ ................................................ --><img src=?> <script src=# language=JavaScript></script></div> */ // ;
  • 24. HTML/CSS in GIF89a GIF89a(q=/*.....Ä=);sub GIF89a{print &quot;Hello Perl!&quot;} __END__#*/1);function GIF89a(){alert(&quot;Hello JavaScrpt!&quot;)} /* <body style=visibility:hidden> <div style=position:relative;visibility:visible> <h1>Hello HTML!</h1> <!-- ................................................ ................................................ ................................................ ................................................ --> <img src=?> <script src=# language=JavaScript></script> </div> */// ;
  • 25. How to break same-origin-policy. (Parallelize cross-domain access) Other GIF89a hacks GIF89a Binary Image Object for AJAX communications Protocol
  • 26. 従来:Ajaxでクロスドメイン通信する方法 1. XMLHttpRequest + Local proxy 非同期通信 API の元祖 XMLHttpRequest クロスドメイン通信ができないので Local proxy パフォーマンスの問題(自サーバの Proxy 経由でアクセス) セキュリティの問題( Open Proxy 悪用の危険性) 2. Flash の力を借りる + crossdomain.xml SocketJS の実装など 3. <script src=“http://.../.js”> の動的生成 JSONP で最近ブーム
  • 27. JSONPの動作原理 function callback (data) { // … ここに処理を書く … } (1)コールバック関数の定義 (2) script tag の動的生成 (3)サーバからのレスポンス クロスドメインで JavaScript 関数を実行 <script src=“http://example.com/data.json? jsonp= callback ” /> callback( { foo: 'This is foo.', bar: 'This is bar.', moe: 'This is moe.' } );
  • 28. GIF89a でクロスドメイン通信 <img src=“null.gif?q=param&quot; onload=“ callback (this.width)&quot;> function callback (data) { //… do action } (1) Define JS callback function (likes JSONP) (2) New Image Object CGI にしても OK http://example.com/webapi/null.gif?q=foobar 戻り値: GIF 画像の幅サイズ
  • 29. 画像ファイルのサイズ比較 画像サイズ 1x1 (モノクロ GIF ) 35 byte 画像サイズ 1000x1000 (モノクロ GIF ) 1,735 byte 画像サイズ 1000x1000 ( 24bpp BMP ) 3,000,054 byte (約 3MB ) 画像サイズ 65535x65535 ( 24bpp BMP ) 約 12GB ワークエリア足りません… orz
  • 30. G I F (tm) Graphics Interchange Format (tm) A standard defining a mechanism for the storage and transmission of raster-based graphics information June 15, 1987 (c) CompuServe Incorporated, 1987 All rights reserved http://members.aol.com/royalef/gif87a.txt
  • 31. GIF87a 仕様書 bits 7 6 5 4 3 2 1 0 Byte # +---------------+ | | 1 +-Screen Width -+ Raster width in pixels (LSB first) | | 2 +---------------+ | | 3 +-Screen Height-+ Raster height in pixels (LSB first) | | 4 +-+-----+-+-----+ M = 1, Global color map follows Descriptor |M| cr |0|pixel| 5 cr+1 = # bits of color resolution +-+-----+-+-----+ pixel+1 = # bits/pixel in image | background | 6 background=Color index of screen background +---------------+ (color is defined from the Global color |0 0 0 0 0 0 0 0| 7 map or default map if none specified) +---------------+
  • 32. 任意の画像幅をできるだけ短く生成したい Image Block の存在しない GIF Header だけ 画像の幅と高さのサイズ情報をサーバで生成 最小で20byte固定長 sub create_gif { my ($width, $height) = @_; my $size = pack &quot;S2&quot;, $width, $height; return &quot;474946383761$sizef00000000000ffffff3b&quot;; } width と height の 16bit ずつ つまり 32bit の情報をサーバ側で GIF 形式にエンコードして渡せる Perl のサンプルコード
  • 34. しかし、 IE では壊れた画像と認識 … orz サイズ情報を読み出せない…
  • 35. GRAPHICS INTERCHANGE FORMAT(sm) Version 89a (c)1987,1988,1989,1990 Copyright CompuServe Incorporated Columbus, Ohio http://www.w3.org/Graphics/GIF/spec-gif89a.txt
  • 36. クロスブラウザ対策 GIF89aの形式にして 1x1のダミーの Image Block を挿入すると IEでも解釈するように http://www.tohoho-web.com/soft/wcnt.htm とほほの WwwCounter で使用されている GIF 画像連結ライブラリの動作原理にインスパイア 独立した一つの Image Block
  • 37. GIFファイルのデータ構造 +-----------------------+ | +-------------------+ | | | GIF Signature | | | +-------------------+ | | +-------------------+ | | | Screen Descriptor | | | +-------------------+ | | +-------------------+ | | | Global Color Map | | | +-------------------+ | |- GIF Terminator -| +-----------------------+ +-----------------------+ | +-------------------+ | | | GIF Signature | | 5byte (GIF89a) | +-------------------+ | | +-------------------+ | | | Screen Descriptor | | 7 byte (width x height) | +-------------------+ | | +-------------------+ | | | Global Color Map | | 6 byte (2 colors) | +-------------------+ | | +-------------------+ | | | IMAGE DESCRIPTOR | | 15 byte (1 x 1) | +-------------------+ | |- GIF Terminator -| 1 byte (;) +-----------------------+ 20 byte 35 byte
  • 38. return 16bit x 2 PerlでのGIF89a出力例(固定長35byte) #!/usr/bin/perl use strict; use warnings; sub create_gif { my $size = pack &quot;S2&quot;, @_; return &quot;GIF89a$sizef00000000000ffffff,&quot; . &quot;0000000001000100000202L0100;&quot;; } print &quot;Content-Length: 35&quot;; print &quot;Content-Type: image/gif&quot;; binmode(*STDOUT); print create_gif(65535, 65535); 1;
  • 40. オールドタイプのためのC言語ライブラリ #include <stdio.h> #define print_gif_head() do { printf( &quot;Content-Length: 35&quot; &quot;Content-Type: image/gif&quot; &quot;&quot;); } while (0) #define print_gif_body(x,y) do { putchar('G'); putchar('I'); putchar('F'); putchar('8'); putchar('9'); putchar('a'); putchar(0xff & (x)); putchar(0xff & (x >> 8)); putchar(0xff & (y)); putchar(0xff & (y >> 8)); putchar(0xf0); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0xff); putchar(0xff); putchar(0xff); putchar(','); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x00); putchar(0x01); putchar(0x00); putchar(0x01); putchar(0x00); putchar(0x00); putchar(0x02); putchar(0x02); putchar('L'); putchar(0x01); putchar(0x00); putchar(';'); } while (0) int main() { print_gif_head(); print_gif_body(65535, 65535); }
  • 41.  
  • 42. !!
  • 44. 歴史の古いGIF規格 GIF GIF87a(1987年) GIF89a(1989年) XML 規格化(1998年) JSON RFC4627(2006年) 20年前の データ交換 フォーマット コンピュータにやさしい バイナリアンにやさしい 地球にやさしい
  • 46. ご清聴ありがとうございました [ 宣伝 ] サイボウズ・ラボでは人材募集中です