「なでしこ」バグ&要望掲示板

なでしこのバグや実現して欲しい機能の要望を行う掲示板です。
[一覧へ] > (@532) [高] [解決]
@532■ (#1688) 「JSONデコード」命令で、null があると失敗する - U D (2010-07-19 22:44) /中 アイデア
【症状】どのような症状、現象か?
【再現方法】サンプルソース、再現手順など

『[1,2,3]』をJSONデコードの変数型確認を表示
『[null]』をJSONデコードの変数型確認を表示

【要望】どのような解決が望ましいか?

null 値は、空文字列か、もしくは NIL として解釈するように。

【バージョン】nadesiko ver.1.5329
【その他】

Twitter 連携ライブラリ「なこったー / nakotter」のβ版を公開しました。
 http://www.undefin.net/nadesiko/xpln/lesson/L3-1

nakotter では、取得データの整形処理が、デフォルトでは「JSONデコード」を
利用するようにしています:

  # HTTP Response の処理。デフォルトでは JSON 想定
  レスポンス処理は~
   レスポンス部分の『:null』を『:""』に置換してJSONデコード

しかし「JSONデコード」命令では null 値があると失敗してしまうため、
暫定的に null を空文字列に置換して利用しています。

XML フォーマットで取得してタグ関連の命令でぐちゃぐちゃとやるのでもいいのですが、
タグ関連の命令はそこまで充実していないし、階層タグ命令等も使いづらいです。
JSONデコードを使ってきちんとなでしこの配列/ハッシュに変換できれば、

 Nakotterから返信取得して反復、対象@`text`を表示

のように、XML で切り盛り(?)するよりも圧倒的に楽です。

----
ということで、null は空文字列か、NIL としてデコードされて欲しいです。
修正案が他にあればお願いします。

(#1693) 巨大な整数でオーバーフロー - U D (2010-07-21 00:58) /中 アイデア
整数型で扱えない巨大な数が現れると、オーバーフローして正しくない数値データが
読み込まれてしまいます(具体的には、 status_id など)。

こちらの対処は難しそうですが、一応報告だけ。

(#1714) 修正済み - クジラ飛行机 (2010-08-11 00:39) /中 確認待ち
-JSONデコードで大きな整数が扱えない問題を修正(r239)(@532)

(#1785) null 問題は未解決 - U D (2010-09-29 00:19) /中 再修正依頼
状態が確認待ちになっていますが、片方、null の問題の方は未解決なので
よろしくお願いします。

# なんかこの前もどっかで同じことを言ったような気もしますが(汗;

//再現コード
A=『[1,null,3]』をJSONデコード。
Aの変数型確認を表示。 // 配列じゃない!
A[0]を表示。// 1 ではない
A[2]を表示。// 3 ではない

(#1866) Re: 「JSONデコード」命令で、null があると失敗する - LSI (2010-12-24 22:55) /中 再修正依頼
こんにちは。LSIです。

なでしこのソースコードを読んでいて、怪しいところを見つけたので、報告します。

unit_kabin.pasのJsonObject2PHiValue()のcase文で、
obj.JsonTypeがjson_type_nullの時、nilを返していますが、
これを空のHiValueオブジェクトへのポインタを返すようにすると、
 U D さんが望んでいる動作になりそうな気がします。

JsonObject2PHiValue()でnilを返していることで、
大本の関数sys_json_decode()でもnilを返すので、
戻り値なしの扱いになっているようです。

ただ、Delphiの開発環境を持っておらず、実際に試したわけではないです。
外していたらごめんなさい。

// 現在のcase文
// ここから
  case obj.JsonType of
    json_type_null:     Result := nil;
    json_type_boolean:  Result := hi_newBool(obj.AsBoolean);
    json_type_string:
    // ……
  end;
// ここまで

// 以下のように変更
// ここから
  case obj.JsonType of
    json_type_null:     Result := hi_var_new;
    json_type_boolean:  Result := hi_newBool(obj.AsBoolean);
    json_type_string:
    // ……
  end;
// ここまで

unit_kabin.pas - JsonObject2PHiValue()
http://code.google.com/p/nadesiko/source/browse/trunk/hi_unit/unit_kabin.pas?r=249#104

(#1937) エンコード、デコード共に不完全 - json (2011-08-25 02:34) /高 再修正依頼
重要度を上げさせていただきます。


JSONデコード、エンコード共に完全ではないようです。
//再現ここから

元ハッシュとはハッシュ
元ハッシュ@"a" = "AAA"
元ハッシュ@"b" = "BBB"
元ハッシュ@"c" = "CCC"
元ハッシュを言う

JSONデータは元ハッシュをJSONエンコード
JSONデータを言う
//ここで末尾に"":nullという無駄なデータが入る

復元ハッシュはJSONデータをJSONデコード
復元ハッシュを言う
//そもそも空が帰ってくる

『{"a":"AAA","b":"BBB","c":"CCC"}』をJSONデコード
それを言う
//正常にデコード出来る
//再現ここまで


これから考えるに、エンコードが悪いようです。
デコードも、最後のnullのせいでうまくいってないように感じます。


JSONはオブジェクトを保存する上でとても大事なので、
改善されることを願っています。


ちなみに、このサンプルは現時点の最新バージョン(1.5332)です

(#1960) 開発者向け修正箇所情報 - うぇいく (2012-03-20 05:22) /高 再修正依頼
・ハッシュをエンコードすると「"":null」というエントリが混ざる
文字列の余分なエリアの切り捨て漏れです。nako_hash_keysの返却値を受け取るようにしてSetLengthすると良さそうです。
----------- unit_kabin.pas(78付近)
    SetLength(s, 1024 * 16);
    i :=nako_hash_keys(p, PAnsiChar(s), 1024 * 16);
    SetLength(s,i);
-----------
・\uXXXXで正しく変換されない文字がある
json.pasがXXXXの16進表記で英大文字を受け付けないためです。'A'..'F'も十六進表記文字の一覧に加えると良さそうです。
-----------json.pas(454付近)
  json_hex_chars = '0123456789abcdef';
  json_hex_chars_set = ['0'..'9','a'..'f','A'..'F'];
-----------
・jsonのデータにnullがあるとデコードで全体が空になる
objがnullの場合のデータを生成していないため。nullに対してはobjがnullというデータとして取得され、json_type_nullは無効なjsonデータのときに使われるようです。
-----------unit_kabin.pas(111付近)
  if obj = nil then
  begin
    Result := hi_var_new;
    Exit;
  end;
-----------
他、jsonのハッシュのキーが非ASCIIの場合、デコードの際にutf8toAnsiを介さず返されるためにキーだけUTF8のままになっています。JSONの仕様上発生しえるのなら、あわせて対処が必要そうです。

(#1962) 感謝 - クジラ飛行机 (2012-04-06 13:56) /高 確認待ち
うぇいくさん、修正情報ありがとうございます。
無事に、エラーが出るサンプルが動くようになりました。
(r254)

(#2660) 修正確認 - クジラ (2016-10-07 20:06) /高 解決

(#1688)へ返信する:

名前
タイトル
本文
優先度
状態
確認キー お手数ですが、いたずら防止のために、「真夏」の読み方を記入してください。
編集キー 編集時に使うキーを入力(省略可能)
添付ファイル 画像ファイル(最大300KB)を添付可能