本当はこわいエンコーディングの話 とみたまさひろ 東京 Ruby 会議 本当はこわいエンコーディングの話 Powered by Rabbit 2.0.6

Similar documents
SOC Report

文字コード略歴 よこやままさふみ社内勉強会 2012/05/18 文字コード略歴 Powered by Rabbit 2.0.6

(Microsoft PowerPoint -

johokiso-char.pdf.pdf

ソフトウェア基礎 Ⅰ Report#2 提出日 : 2009 年 8 月 11 日 所属 : 工学部情報工学科 学籍番号 : K 氏名 : 當銘孔太

Apache-Tomcat と 冗長な UTF-8 表現 (CVE 検証レポート ) 2008 年 08 月 26 日 Ver. 0.1

Microsoft PowerPoint - char-1605temp.ppt [互換モード]

多言語ドメイン名の実装 mdnkit 石曽根信 ( 株 ) SRA 2001/12/04 日本語ドメイン名解説 / mdnkit 1 mdnkit 多言語ドメイン名を扱うためのツールキット 正規化 エンコード変換等を提供するライブラリとコマンド 既存アプリケーシ

メール誤送信対策<利用者編> ご利用の手引き

自己紹介 とみたまさひろ MySQL 3.21 に日本語 charsetを追加 MySQLのRubyバインディング作成

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

スライド 1

SOC Report

自己紹介 twitter や github

( )!?

PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 文字列 文字列リテラル プログラムの中で文字列を表す方法は幾つか有るが 基本的な方法は下記の 2 種で有る 対象と成る文字の集まりをダブルクオーテーション ( " ) で囲うか シングルクオーテーション ( ' ) で囲う PYTHON3 "

ohp.mgp

管理番号 内容仮想テーブル設定画面およびマッチング条件設定画面においてコメントを設定した場合 変換エラーが発生する マッピング情報設定画面の出力情報に固定値を選択し区分に 動的バイナリ値 を指定した場合 関数を設定す

MySQL Cluster

変換が必要なもの 1.Stata13( またはそれ以前 ) で保存した以下のもので 拡張 ASCII 文字 ( 日本語フォントなど ) が含まれるもの dta ファイル do ファイル ado ファイル smcl ファイル log ファイル ( gph ファイル stsem ファイル stpr ファ

(2 Linux Mozilla [ ] [ ] [ ] [ ] URL 2 qkc, nkc ~/.cshrc (emacs 2 set path=($path /usr/meiji/pub/linux/bin tcsh b

テキストの保存形式と外国語テキストの保存

MySQL 日本語処理完全解説 住商情報システム株式会社プラットフォームソリューション事業部門 IT 基盤ソリューション事業部オープンソースシステム部玉川修一 1

スライド 1

HULFT-DataMagic for Windows Ver レベルアップ詳細情報 < 製品一覧 > 製品名 バージョン HULFT-DataMagic for Windows HULFT-DataMagic コード変換 オプション for Windows HU

SideAceユーザーズガイド

Android Layout SDK プログラミング マニュアル

基礎プログラミング2015

g_get_charset の返値になる すなわち現在のロケールの文字符号化方式になる 環境変数 G_FILENAME_ENCODING と G_BROKEN_FILENAMES の両方が定義されていない時には file name encoding の実体は になる バージョン G_FILENAME

CONTEC DIOプロバイダ ユーザーズガイド

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

4 Mule(Emacs)

農業・農村基盤図の大字小字コードXML作成 説明書

JavaプログラミングⅠ

iNFUSE インフューズ

untitled

RT Fontカタログ

文字コード (2) 林部祐太 国立国会図書館関西館電子図書館課 2013/9/27 1

Sequel のすすめ 私が SQL を嫌いな理由 とみたまさひろ RubyHiroba Sequel のすすめ - 私が SQL を嫌いな理由 Powered by Rabbit 2.0.7

untitled

SideAceユーザーズガイド

( ) Shift JIS ( ) ASCII ASCII ( ) 8bit = 1 Byte JIS(Japan Industrial Standard) X 0201 (X ) 2 Byte JIS ISO-2022-JP, Shift JIS, EUC 1 Byte 2 By

¥ƥ­¥¹¥ȥ¨¥ǥ£¥¿¤λȤ¤˽

AquesTalk for WinCE プログラミングガイド

AquesTalk2 Mac マニュアル

Delphi/400バージョンアップに伴う文字コードの違いと制御

23_33.indd

<4D F736F F D20837D836A B5F93C192E88C AC888D593FC97CD5F2E646F63>

SiTCP ユーティリティユーザガイド 2014 年 6 月 18 日 0.73 版 Bee Beans Technologies 1

XML ( ) XML XML jedit XML XPath XSLT jedit JAVA VM jedit Slava Pestov GNU GPL ( ) jedit jedit ( jedit XML jed

Nucleus CMS 4.0 の新機能 日本語版リリースマネジャー兼メインコミッター坂本貴史

WEBシステムのセキュリティ技術

C プログラミング 1( 再 ) 第 4 回 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ 1

3.Cygwin で日本語を使いたい Cygwin で以下のコマンドを実行すると それ以降 メッセージが日本語になります export LANG=ja_JP.UTF-8 これは 文字コードを日本語の UTF-8 に設定することを意味しています UTF-8 は Cygwin で標準の文字コードで, 多

自己紹介 とみたまさひろプログラマー (Ruby & C) 日本 MySQLユーザ会代表

文字コードとその実装

このダイナミックリンクライブラリ GaugeC48.dll は 8CH から 48CH 用の DigitalGaugeCounterDG3000 シリーズ共通の DLL です この説明書は GaugeC48.dll を使ったアプリケーションを作成するためのものです 開発環境は MicrosoftVi

AquesTalk Mac マニュアル

SQLインジェクション対策再考

UIOUSBCOM.DLLコマンドリファレンス

HULFT-DataMagic for Linux Ver リビジョンアップ詳細情報 < 製品一覧 > 製品名 バージョン HULFT-DataMagic for Linux HULFT-DataMagic コード変換 オプション for Linux HULFT-

よくある質問 Q1. 署名付きメールを受信後 署名アイコンをクリックしてメッセージの作成者から正常に送信されていることを確認しましたが 取り消し状態 に デジタル ID の確認が無効になっています と表示されました (Outlook Express6 Windows Mail) 初期設定では 証明書

基本的な利用法

ユーティリティ 管理番号 内容 対象バージョン 157 管理情報バッチ登録コマンド (utliupdt) のメッセージ出力に対し リダイレクトまたはパイプを使用すると メッセージが途中までしか出 力されないことがある 267 転送集計コマンド (utllogcnt) でファイル ID とホスト名の組


ネットワークシステム管理 #01

改訂履歴

Java Scriptプログラミング入門 3.6~ 茨城大学工学部情報工学科 08T4018Y 小幡智裕

1 ユーザ認証を受けた権限で アプリケーションを利用するために ログインプロキシにアクセスします 2 ログインプロキシにより Shibboleth SP から Shibboleth IdP の認証画面にリダイレクトされます 3 ブラウザに認証画面を表示します 4 認証画面にユーザ / パスワードを入

NEC COBOL Media V2.0 セットアップカード SL438740B01-1

24th Embarcadero Developer Camp

Report#2.docx

Report#2.docx

Prog2_10th

iNFUSE インフューズ

Windowsテキストファイル操作ノウハウ

別紙 1 無線局等情報検索 Web-API のリクエスト条件一覧 (Ver.1.1.1) 平成 31 年 2 月

2016 年 8 月 第 1.0 版 ラトックシステム株式会社


計算機概論

Prog1_12th

NEC Express5800 シリーズ COBOL Media V1 セットアップカード SL438730B01-2

日医標準レセプトソフト クラウド版の構築手順

n..

Canon EOS Kiss Digital N 製品カタログ

h1

システムパッケージリリース情報-Version5.0.0pre

Drive-by-Download攻撃における通信の 定性的特徴とその遷移を捉えた検知方式

SjisEucユーザーズガイド

ネットワークシステム管理 #01

joho07-1.ppt

XML基礎

パケットモニター (Wireshark) の使い方 第 1 版 1.Wireshark とは ネットワーク上 (LAN ケーブルに流れている ) のパケットを取得して その中の情報を画面に表示するソフトウェア (LAN アナライザーまたはパケットモニター ) の 1 つに Wiresh

Microsoft PowerPoint _Encoding.pptx

intra-mart Accel Platform — IM-共通マスタ スマートフォン拡張プログラミングガイド   初版  

MODBUS ユーザーズマニュアル 페이지 1 / 23

PowerPoint Presentation

ConMas Manager データ取り込みレイアウト Copyright 2012 CIMTOPS CORPORATION - All Rights Reserved.

本書は INpMac v2.20(intime 5.2 INplc 3 Windows7/8/8.1に対応 ) の内容を元に記載しています Microsoft Windows Visual Studio は 米国 Microsoft Corporation の米国及びその他の国における登録商標です

スーパー英語アカデミック版Ver.2

Transcription:

本当はこわいエンコーディングの話 とみたまさひろ 東京 Ruby 会議 10 2013-01-13

とみたまさひろ 自己紹介 http://tmtms.hatenablog.com https://twitter.com/tmtms 好きなもの / 環境 Ruby, Rabbit, MySQL, Emacs, Git, Ubuntu, ThinkPad 所属など 長野県北部在住 / 某社プログラマー / 日本 MySQL ユーザ会 / 長野ソフトウェア技術者グループ (NSEG)

エンコーディング

エンコーディングとは 文字符号化方式 文字をどのようなバイト列で表現するか UTF-8 とか EUC-JP とか SHIFT_JIS とかそーゆー奴 charset とか呼ばれたりする 文字コード とか呼ばれたりする

同じバイト列でも別の文字 0xC2 0xA9 の2バイトは UTF-8 では 1 文字 EUC-JP では 息 1 文字 SHIFT_JIS では ツゥ 2 文字

Ruby 1.8 "\xc2\xa9" という文字列は Ruby 的にはただのバイト列 エンコーディング情報を持たない " "(UTF-8) として扱うか " 息 "(EUC-JP) として扱うかはプログラム次第 正規表現にはエンコーディングあり / /n / /s / /u / /e

Ruby 1.9 文字列のエンコーディングは文字列自身が知っている " "(UTF-8) と " 息 "(EUC-JP) は同じバイト列だけど異なる文字列 " あ "(UTF-8) と " あ "(EUC-JP) は同じ文字を表してるけど等しくない 同じプログラム中で複数のエンコーディングの文字列を同時に扱える ( 珍しいかも ) 正規表現にもエンコーディングあり

エンコーディング一覧 (1.9.3) Ruby 自身が持ってるので環境に依存しない ASCII-8BIT Big5 Big5-HKSCS Big5-UAO CP50220 CP50221 CP51932 CP850 CP852 CP855 CP949 CP950 CP951 EUC-JP EUC-KR EUC-TW Emacs-Mule GB12345 GB18030 GB1988 GB2312 GBK IBM437 IBM737 IBM775 IBM852 IBM855 IBM857 IBM860 IBM861 IBM862 IBM863 IBM864 IBM865 IBM866 IBM869 ISO-2022-JP ISO-2022-JP-2 ISO-2022-JP-KDDI ISO-8859-1 ISO-8859-10 ISO-8859-11 ISO-8859-13 ISO-8859-14 ISO-8859-15 ISO-8859-16 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-6 ISO-8859-7 ISO-8859-8 ISO-8859-9 KOI8-R KOI8-U MacJapanese SJIS-DoCoMo SJIS-KDDI SJIS-SoftBank Shift_JIS TIS-620 US-ASCII UTF-16 UTF-16BE UTF-16LE UTF-32 UTF-32BE UTF-32LE UTF-7 UTF-8 UTF8-DoCoMo UTF8-KDDI UTF8-MAC UTF8-SoftBank Windows-1250 Windows-1251 Windows-1252 Windows-1253 Windows-1254 Windows-1255 Windows-1256 Windows-1257 Windows-1258 Windows-31J Windows-874 eucjp-ms maccenteuro maccroatian maccyrillic macgreek maciceland macroman macromania macthai macturkish macukraine stateless-iso-2022-jp stateless-iso-2022-jp-kddi

うれしいこと

1.8 ではバイト単位 " あいう ".size #=> 9 " あいう ".bytesize #=> 9 " あいう ".chars{ c... } #=> "\xe3","\x81","\x82",... " あいう "[0] #=> 0xE3 " あいう ".reverse #=> "\x86\x81\xe3\x84\x81\xe3\x82\x81\xe3"

1.9 では文字単位 " あいう ".size #=> 3 " あいう ".bytesize #=> 9 " あいう ".chars{ c... } #=> " あ ", " い ", " う " " あいう "[0] #=> " あ " " あいう ".reverse #=> " ういあ "

エンコーディング変換 # -*- coding: utf-8 -*- s = " あいう " #=> "\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86" s.encoding #=> #<Encoding:UTF-8> s2 = s.encode("cp932") #=> "\x82\xa0\x82\xa2\x82\xa4" s2.encoding #=> #<Encoding:Windows-31J>

IO で変換してくれる File.open("cp932.txt", "r:cp932").read #=> CP932 文字列 File.open("cp932.txt", "r:cp932:utf-8").read #=> UTF-8 文字列 File.open("cp932.txt").read #=> 環境依存

うれしいことばかりじゃない

変換先にない文字 # -*- coding: utf-8 -*- " あ ".encode("cp932") #=> Encoding::UndefinedConversionError

変換元にない文字 # -*- coding: utf-8 -*- " あ \xff".encode("cp932") #=> Encoding::InvalidByteSequenceError

エンコーディングがあっても変換できるとは限らない # -*- coding: utf-8 -*- " あいう ".encode("utf-7") #=> Encoding::ConverterNotFoundError

エンコーディングの不一致 utf8 = " あいう " cp932 = " あ ".encode("cp932") utf8.start_with?(cp932) #=> Encoding::CompatibilityError

文字列と正規表現のエンコーディングの不一致 utf8 = " あいう " re = /./s utf8 =~ re #=> Encoding::CompatibilityError

エンコーディングが同じでも不正な文字を含んでいる utf8 = " あ \xff" utf8 =~ /./ #=> invalid byte sequence in UTF-8 # (ArgumentError)

IO

メソッドによってエンコーディングが異なる テキスト読み込み ( エンコードあり ) IO#gets IO#getc IO#lines IO#read 等 バイナリ読み込み (ASCII-8BIT 固定 ) IO#read(n) IO#sysread 等

IO#read IO#read(size) は ASCII-8BIT IO#read() は外部エンコーディング依存 引数の有無によって結果のエンコーディングが異なる! なにそれこわい

外部エンコーディング ファイル自身は自分の内容のエンコーディングを知らない ファイルから読み込んだ文字列の Ruby 内でのエンコーディングは何らかの方法で指定する必要がある

引数で指定 File.open(filename, "r:utf-8") File.read(filename, :encoding=>"utf-8")

環境変数 引数で指定されてない場合は環境変数が参照される LC_ALL LC_CTYPE LANG

環境変数による違い % cat utf-8.txt あいうえお % export LC_ALL=C % ruby -e 'p File.read("utf-8.txt").size' 16 % export LC_ALL=ja_JP.UTF-8 % ruby -e 'p File.read("utf-8.txt").size' 6 環境変数によって動きが変わっちゃう! こわい

入力時にはエラーにならない utf8 = File.read("utf8.txt", :encoding=>"utf-8") # 実は UTF-8 として不正な文字が含まれていて # ずっと後で別のメソッドでエラーになったり utf8 =~ /./ #=> invalid byte sequence in UTF-8 (ArgumentError)

CGI require "cgi" cgi = CGI.new 不正な文字のパラメータを渡すとエラー GET http://example.com/hoge.cgi?fuga=%ff #=> Accept-Charset encoding error (CGI::InvalidEncoding)

Rails 不正な文字のパラメータを渡すとエラー POST http://example.com/posts post[title]=%ff #=> ArgumentError (invalid byte sequence in UTF-8)

エラーになりすぎこわい!

対処

変換先にない文字を置換 " あ ".encode("cp932") #=> Encoding::UndefinedConversionError " あ ".encode("cp932", :undef=>:replace) #=> " あ?"

変換元にない文字を置換 " あ \xff".encode("cp932") #=> Encoding::InvalidByteSequenceError " あ \xff".encode("cp932", :invalid=>:replace) #=> " あ?"

置換文字の指定 " あ ".encode("cp932", :undef=>:replace, :replace=>" ") #=> CP932 で " あ "

そもそも変換が必要になるようなことをしないのが吉

UTF-8 に統一すればたいていは問題ない

UTF-8 に統一したつもりでも他のエンコーディングが現れることも File.open(filename, "r:utf-8").read #=> UTF-8 文字列 File.open(filename).read #=> 環境依存

いちいち引数で指定する?

デフォルト値を指定する プログラムで使用するファイルのエンコーディングがすべて同一であれば Encoding.default_external = "UTF-8" File.read(filename) #=> UTF-8 文字列

これで問題ない?

ASCII-8BIT

メソッドによっては ASCII-8BIT