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;\x47\x49\x46\x38\x37\x61$size\xf0\x00\x00\x00\x00\x00\xff\xff\xff\x3b&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$size\xf0\x00\x00\x00\x00\x00\xff\xff\xff,&quot; . &quot;\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02L\x01\x00;&quot;; } print &quot;Content-Length: 35\n&quot;; print &quot;Content-Type: image/gif\n\n&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\n&quot; \ &quot;Content-Type: image/gif\n&quot; \ &quot;\n&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年前の データ交換 フォーマット コンピュータにやさしい バイナリアンにやさしい 地球にやさしい
温故知新
ご清聴ありがとうございました [ 宣伝 ]  サイボウズ・ラボでは人材募集中です

GIF89a Oldtype

  • 1.
    JavaScript の世代間を埋めるパーツ - 過去と未来をつなぐ GIF89a - サイボウズ・ラボ株式会社 竹迫 良範 Real UNIX MAGAZINE Day (2007/11/03)
  • 2.
  • 3.
    http://0xcc.net/misc/ggap.html  より Binary2.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 - inputdevice ??? 0 key ?
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
    HTML/CSS & JS& Perl in GIF89a (valid) Web Polyglot
  • 18.
  • 19.
    5秒でわかる Polyglot (JavaScriptin GIF89a) 正しい GIF 画像でもある JavaScript ファイル JavaScript として実行できる GIF 画像ファイル IE/Firefox/Opera/Safari できちんと動作 <script src=“alert0.gif” language=“JavaScript”>
  • 20.
    Web Polyglot DEMOHTML/CSS & JS & Perl in GIF89a (valid)
  • 21.
  • 22.
    Perl in GIF89aGIF89a(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 GIF89aGIF89a( 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 GIF89aGIF89a(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 breaksame-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 でクロスドメイン通信 <imgsrc=“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 仕様書 bits7 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;\x47\x49\x46\x38\x37\x61$size\xf0\x00\x00\x00\x00\x00\xff\xff\xff\x3b&quot;; } width と height の 16bit ずつ つまり 32bit の情報をサーバ側で GIF 形式にエンコードして渡せる Perl のサンプルコード
  • 33.
  • 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 x2 PerlでのGIF89a出力例(固定長35byte) #!/usr/bin/perl use strict; use warnings; sub create_gif { my $size = pack &quot;S2&quot;, @_; return &quot;GIF89a$size\xf0\x00\x00\x00\x00\x00\xff\xff\xff,&quot; . &quot;\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02L\x01\x00;&quot;; } print &quot;Content-Length: 35\n&quot;; print &quot;Content-Type: image/gif\n\n&quot;; binmode(*STDOUT); print create_gif(65535, 65535); 1;
  • 39.
  • 40.
    オールドタイプのためのC言語ライブラリ #include <stdio.h>#define print_gif_head() do { \ printf( \ &quot;Content-Length: 35\n&quot; \ &quot;Content-Type: image/gif\n&quot; \ &quot;\n&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.
  • 43.
  • 44.
    歴史の古いGIF規格 GIF GIF87a(1987年)GIF89a(1989年) XML 規格化(1998年) JSON RFC4627(2006年) 20年前の データ交換 フォーマット コンピュータにやさしい バイナリアンにやさしい 地球にやさしい
  • 45.
  • 46.
    ご清聴ありがとうございました [ 宣伝] サイボウズ・ラボでは人材募集中です