メインコンテンツへスキップ

Sj.h C99でたった150行!驚きの超軽量JSONパースライブラリ

·2 分
2025/09 C言語 JSON プログラミング ライブラリ 軽量

Sj.h C99でたった150行!驚きの超軽量JSONパースライブラリ

引用元:https://news.ycombinator.com/item?id=45324349

lioeters 2025/09/21 17:26:23

この著者の作品はANSI CかLuaの単一ファイルライブラリで、スコープが絞られてて使いやすい。ドキュメントも充実してて、フリーソフトウェアライセンスなんだって。log.c、microui、fe、microtar、cembed、ini、json.lua、lite、cmixer、uuid4とか色々あるみたいだよ。

maldonad0 2025/09/21 21:02:57

それってオープンソースで、フリーソフトウェアじゃないよ。

tonypapousek 2025/09/21 21:07:49

ライセンスは違うこと言ってるよ。パブリックドメインより自由なものってないしね。

SoKamil 2025/09/21 21:18:37

一般的な企業のセキュリティ部門ってパブリックドメインのソフトウェアについてどう考えてるんだろう?そういうライセンス(またはライセンスなし)のソフトウェアを受け入れるのかな?

jen20 2025/09/21 21:38:22

誰が気にするの?真面目な話、君の作品を使いたい企業がライセンスを受け入れるかどうかは、リヒテンシュタインの首相がアメリカの家の外壁の色を気に入るかどうかと一緒だよ。つまり、全然気にすることじゃないってこと。

tripplyons 2025/09/21 21:17:27

「フリーソフトウェア」より「オープンソース」の方が情報量が多い言葉だよ。全てのフリーソフトウェアがオープンソースってわけじゃないけど、全てのオープンソースソフトウェアは無料なんだ。追記:FSFの定義は知らなかったんだ。有料じゃないソフトウェアをフリーソフトウェアとして使ってたよ。

F3nd0 2025/09/21 21:25:48

‘フリーソフトウェア’と‘オープンソースソフトウェア’は(それぞれFSFとOSIの定義によって、実際にはそう使われるんだけど)定義が重なってるよ。このプロジェクトはUnlicenseを通してパブリックドメインでリリースされてて、これはフリーソフトウェアの’ライセンス’として認められるんだ。他の多くのプロジェクトはMIT/Expatライセンスを使ってて、これもフリーソフトウェアライセンスだよ。
https://www.gnu.org/philosophy/free-sw.html
https://opensource.org/osd

rerdavies 2025/09/22 00:50:19

それって、みんなが使えるようにオープンソースソフトウェアを公開してるかどうかによるよね。もしそうじゃないなら、なんで公開してるの?使ってほしくないならGPLが良いし、使ってほしいならMITかBSDの方がずっといいよ。

ramses0 2025/09/21 21:35:56

君が探してるのは”Source Available”と”Open Source”(OSI承認ライセンス付き)っていう言葉だよ。”自由な(Free as in speech)のか、無料の(Free as in beer)なのか?”が君のスローガンだね。

rerdavies 2025/09/22 00:54:51

GPLライセンスのソフトウェアだと「エボラみたいな自由」って感じだよね。空気や太陽の光みたいな自由はどこ行っちゃったの?

olivia-banks 2025/09/22 00:36:43

C言語プロジェクトでlog.cをよく使うよ!作者がこんなに多作だとは思わなかったな。log.cは本当にオススメ。必要な機能を簡単に追加できるからね。

F3nd0 2025/09/21 21:31:22

君は間違ってると思うよ。オープンソースとフリーソフトウェアは、どっちかがどっちかの部分集合じゃないんだ。OSIはオープンソースって認めても、FSFはフリーって認めないライセンスとか、逆もあるしね[1]。 massiveな重複はあるけど、根本的に別の定義って言うのが適切じゃないかな。
[1] https://spdx.org/licenses/

rerdavies 2025/09/21 22:50:17

で、それがどうやってオープンソースライセンスの資格がないって言うの?俺が見る限り、定義を満たしてるように見えるんだけど。

captbaritone 2025/09/21 21:21:41

SQLiteがパブリックドメインをライセンスに選んだことで、結構問題があったって聞いたよ。後悔してるらしい。国際的に理解が広まってない概念で、ソフトウェアの文脈での法的判例も少ないから、法務部門の懸念で採用が難しいチームもあったんだってさ。

xigoi 2025/09/22 04:17:30

GPLはみんなに使ってほしい時に使うもの。MITは、大企業がそれをenshittifiedなプロプライエタリソフトウェアに変えて、あなたに何も還元せずに利益を上げてもいい時に使うものだよ。

typpilol 2025/09/21 22:20:26

俺もUnlicenseを使ってるよ。文字通り、持てる中で一番許諾的なライセンスだからね 笑

manbash 2025/09/21 21:31:16

「全てのフリーソフトウェアがオープンソースってわけじゃない」ってコメントだけど、それはどの”フリーソフトウェア”の定義を言ってるかによるね。FSFの定義では、フリーソフトウェアはオープンソースであることが必須なんだよ。

a96 2025/09/22 06:42:29

それは、守るものが何もなかったからenshittifiedになっちゃったんだよ。

_puk 2025/09/21 21:51:37

例えが悪いね。もし彼らが本当に君の家の色を気にするなら、いくらでも手はあるだろう。だって、かなりの数のアメリカの大企業の税制や企業構造は、リヒテンシュタイン政府のルールに大きく依存してるんだからさ。

jen20 2025/09/22 01:11:14

HOAや地方議会みたいに、良くも悪くも影響力を持つ人達がいるよね。でもリヒテンシュタイン政府にはそういうのがないって話。

zelphirkalt 2025/09/22 09:21:51

反対意見として、僕はMITライセンスよりGPLやAGPLのコードを使いたいな。コピーレフトの哲学が好きだから。GPLはフリーソフトウェアであり続けたいって意思表示だし、MITは将来的にプロプライエタリ化されるリスクがある。だからGPLの方が信頼できるし、みんなのためになると思うよ。

jen20 2025/09/22 01:10:09

Linux、Git、GNUシステムは反例だよね。FreeBSDは毎日衰退してるし。一般の人々と企業の法務部は違うんだよ。

shiomiru 2025/09/21 23:11:21

Unlicenseは単なるパブリックドメインじゃないよ。PDが認められなくても「コピー、変更、公開、使用、コンパイル、販売、配布」を許可するフォールバック条項があるんだ。SQLiteは著作権を放棄するだけだから、最初の文が駄目だとあまり役立たないかもね。

TZubiri 2025/09/22 04:34:16

「みんなに使われたくないならGPLがいい」って、それ笑っちゃうね。

Cogito 2025/09/21 23:09:26

オープンソースじゃないとは言ってないよ。問題はフリーライセンスかどうかだったんだ。「フリーソフトウェアじゃない」って言ってたけど、実際はそうだよ。F3nd0が言ったように、両方なんだよね。

HighGoldstein 2025/09/22 11:39:16

Unlicenseの注意点だけど、一部の法域では機能しないことがあるんだ。その場合、著作権者以外は誰も使えない「文字通りライセンスなし」と見なされるかも。現実には訴えられることはないと思うけど、頭に入れておいて損はないよ。だから多くの団体はCC0やMITを推奨してるんだ。

tonypapousek 2025/09/21 22:20:50

アメリカの視点だと、セキュリティに関してMITライセンスとの実質的な違いはないよ。企業はパッケージがちゃんとメンテされててバグがなく、脆弱性データベースに既知の攻撃がないかを重視するからね。あくまで僕の経験だけど、他の会社はもっと厳しい条件があるかもね。

TZubiri 2025/09/22 04:36:34

Stallmanの信奉者たちを召喚する呪文を唱えるのに成功したね。
追加の提案なんだけど、無料でただな「無料」を指すのには”gratis”も使えるよ。ラテン語由来で、スペイン語圏の国々では「無料」を意味するのに普通に使われるけど、自由の方の「無料」とは意味が違うんだ。

xigoi 2025/09/22 04:20:19

追記:FSFの定義を知らなかったんだ。僕は、お金を払わずに使えるソフトウェアをフリーソフトウェアだと思ってたよ。
それは「フリーウェア」って呼ばれるものだね。それに、オープンソースソフトウェアは有料でも良いんだ(ただし、誰かがそれを買ったら、無料で再配布することを許可しないといけないけどね)。

layer8 2025/09/21 17:54:52

このライブラリ、符号付き整数オーバーフローをチェックしてない箇所があるよ:
https://github.com/rxi/sj.h/blob/eb725e0858877e86932128836c1
https://github.com/rxi/sj.h/blob/eb725e0858877e86932128836c1
https://github.com/rxi/sj.h/blob/eb725e0858877e86932128836c1
特定の入力で未定義動作(UB)が起きる可能性があるね。

もっとコメントを表示(1)
skydhash 2025/09/21 18:08:09

肥大化したエッジケースライブラリについての良い記事があったね([0]: https://43081j.com/2025/09/bloat-of-edge-case-libraries, [1]: https://news.ycombinator.com/item?id=45319399)。
全ての可能性のあるエラーを処理しようとすると、すぐに複雑になっちゃうから、それがライブラリの責任じゃないこともあるんだよ。

hypeatei 2025/09/21 18:38:14

あなたは、一部の開発者が好む、シンプルなシングルヘッダCライブラリ文化を知らないんだね。Tsoding(ストリーマー)なんかがその代表例だよ。彼らは、こういうものが”セキュリティ”や”機能”に焦点を当ててないことを分かってて、それで良いんだって思ってる。全てのものが、何千もの有料顧客にさらされる超真剣なビジネスプロジェクトである必要はないからね。

klysm 2025/09/21 18:33:52

これには強く反対だよ。JSONは信頼できないソースから来る可能性があるし、これはセキュリティ上の影響がある問題だ。肥大化に関する記事が議論してるのは、インターフェースの契約が悪いっていう問題で、それとは種類が違うよ。

ricardobeat 2025/09/21 18:16:50

intは最近のプラットフォームなら32ビットだから、オーバーフローが起きるには、それぞれの行で、
・20億を超える深さにネストされたJSONファイル
・20億行以上のファイル
・20億文字以上の行
が必要ってことだね。

leptons 2025/09/21 19:57:54

システム全体を制御していれば、JSONが必ずしも信頼できないソースから来るわけじゃないよ。システムを制御している限り、全てが絶対100%セキュアである必要はないんだ。公開システムならセキュリティに努めるべきだけど、パブリックな入力を処理しないプロジェクトでは必ずしも必要じゃない。
例えば、僕がアセンブリ言語で書いた簡易JSONパーサーは、シリアルポート経由で組み込みCPUに送られる制御メッセージを解析するものだったんだけど、カメラを回して写真を撮る小さなモーターを制御するやつでね。システムに”信頼できない”JSONが入る方法は全くなかったよ。完璧に機能したし、モーターを制御する組み込みデバイスにすごくシンプルなJSONパーサーがあっても、何も危うくなることはなかったんだ。

layer8 2025/09/21 18:44:53

趣味のプロジェクトって、いつの間にか本番コードで使われ始めて、後でCVEになっちゃう傾向があるんだ。もし意図的に安全性を無視するなら、そのことについてREADMEに目立つ警告を載せるべきだよ。

zwnow 2025/09/21 18:41:50

じゃあ、もしそれが少人数のために設計された趣味のプロジェクトだとしたら、手抜きで彼らを危険に晒すのは急に大丈夫になるってこと?

klysm 2025/09/21 18:34:39

実際のシステムだと20億文字ってのは普通にありそうだよな。

flykespice 2025/09/21 18:44:45

C言語でやるなら、ありとあらゆる未定義動作(UB)を徹底的にチェックするか、別の言語に乗り換えるしかないよ(後者がおすすめ)。

naasking 2025/09/21 19:14:21

1つのJSONファイルで2GBは流石に異例でしょ。このヘッダを使う時の簡単な注意書きで十分だよ。『入力は2GB未満にしてください』とかね。

hypeatei 2025/09/21 18:44:04

これは別に使う義務もないし、お金を払ったわけでもないオープンソースプロジェクトだよ。誰が危険に晒されるって言うんだ?ライセンスにも作者は損害賠償の責任を負わないって明記されてるし。

hypeatei 2025/09/21 18:47:22

>趣味プロジェクトが実用的なら製品コードに使われる傾向があるって言うけど、それが作者の問題なわけ?ライセンスには損害賠償の責任はないってハッキリ書いてあるよ。もしそんな真剣なプロジェクトを開発してるなら、適切な審査プロセスや依存関係のサポート契約が必要だろ。

userbinator 2025/09/21 20:09:09

たぶん、相手側の制御はしてなかったんでしょ?そうでなければ、JSONよりもっとまともなものを使ってたんじゃない?

jeroenhd 2025/09/21 19:56:43

チェック付きインクリメントがデフォルトのプログラミング言語はほとんどないよ。RustやJavaのプログラマーだって同じ間違いをするだろうね。他の言語みたいにチェック付き加算をする関数を書くのも、そんなに難しくないし。

leptons 2025/09/21 21:18:33

俺は両端を制御してたよ。JSONに変なところなんてないね。多くの用途で広く使われてる。JSONを送るシステムはNode.jsベースだったから、JSONを使うのは自然だった。それに、俺がそうしたかったからJSONを使ったんだ。どうせなら他のプロトコルを発明しなきゃいけなかっただろうし、アセンブリ言語で基本的なJSONパーサーを書くのが簡単だって思った時に、車輪の再発明をする気はなかったね(組み込みシステムで40年間アセンブリをコーディングしてきたから)。

layer8 2025/09/21 18:50:56

作者の問題だとは言ってないよ。コードの問題だね。

layer8 2025/09/21 18:17:18

今回の問題は、呼び出し側が制限を知らされていないから、サポート外の入力を渡すのを防ぐことも期待できないし、オーバーフローケースを後から処理する方法もないってことだね。

userbinator 2025/09/21 22:10:43

簡単なものならJSONよりカスタムバイナリプロトコルかASN.1を選ぶな。HLLからの生成もLLLでのパースも楽だろ(俺も数十年Asm書いてるし)。

ethanwillis 2025/09/21 21:01:14

なんでこんな言葉遊びしてんだ? 作者の問題だって言いたいのか? お金を払いたくないプロダクション\ビジネスユーザーのために、READMEに警告を追記しろとまで言うのかよ。

flykespice 2025/09/21 18:52:39

…で、オープンソースのソフトウェアライセンスで、作者が損害賠償の責任を負うものなんて、この世にどんなのあるんだ?

skydhash 2025/09/21 18:25:14

プロジェクトにライブラリを追加するとき、レビューしないのか? forgeのissueを見るか、コードを読めよ。コードが究極の仕様だ。ドキュメントと違う挙動や説明不足は信用しない。再帰やループの処理は特にチェックする。オーバーフロー処理がないなら、コードをFork\Vendorしてアサーションを追加すればいい。

ghurtado 2025/09/21 21:27:28

「システムを制御している限り、何もかも100%安全である必要はない」ってのは、「家に入れるのが自分だけなら、家のセキュリティを心配する必要はない」って言ってるようなもんじゃないのか?

koolba 2025/09/21 19:30:27

「安全性を無視するなら、READMEに警告が必要だ」って言うけど、LICENSEのこの条項はどう思う?「ソフトウェアは“現状有姿”で提供され、いかなる保証もなく、作者は損害賠償の責任を負わない」って明記されてるじゃん。

modeless 2025/09/21 23:04:44

こんなライブラリにセキュリティは期待しないな。メモリセーフにしたければ、Fil-Cでコンパイルすればいいだろ。

k_roy 2025/09/21 19:30:17

おそらく、ライセンスに明示的な責任に関する記述が不足しているってことだろ。

johnisgood 2025/09/22 08:38:51

同感だね。JSONが変わらないと分かってたから、たった10行のパーサーを書いたよ。JSONパーサーとは言えないけど、俺が必要とするものはちゃんとパースしてくれるんだ。

maleldil 2025/09/21 20:24:42

いや、違うね。俺はこれ毎日扱ってるんだ。もしライブラリに入力サイズの制限があるなら、それを明記すべきだろ。

habibur 2025/09/21 22:47:18

レベル深度が20億超えるか、行数が20億超えるとUBになるぜ。JSON入力は1GBまでにしろよ。Web経由で2GBのJSONファイルを受け取ったら、スタックの他の部分でもっと問題が起きるだろうしな。もし2GB超えるファイルで動かしたいなら、ソースのintを全部64bitに変えるぜ。でも入力が2^64超えたら結局クラッシュだろ。コードでintオーバーフローのチェックなんて絶対しねぇよ。

layer8 2025/09/21 23:09:44

これ、メモリ安全性とは全然関係ねぇよ。

ranger_danger 2025/09/21 19:29:02

あんたの言う『古くない』ってどういう意味だよ?今でも32ビット整数がない組み込みシステムが作られてんだぜ。

もっとコメントを表示(2)
LiamPowell 2025/09/21 21:05:22

これ、かなり寛容だよな。悪いことじゃないけど(コード見ずに使う奴のために注意書きはいるかもな)、でもだからこそこんなに小さくできるんだぜ。readmeのデモだと、{”x”,10eee”y”22:5,{[:::,,}]”w”7”h”33って入力がrect: { 10, 22, 7, 33 }になるんだぜ。

hacker_homie 2025/09/22 00:04:14

パーサーってのは入力が正しいと仮定してるもんだろ。バリデーションは別の問題で、このライブラリの管轄外だ。ただデータを抽出するだけのライブラリを他にどう呼べってんだよ。

codr7 2025/09/21 17:36:20

個人的には、JSONパーサーライブラリ全般は苦しみのブラックホールだよ。だいたい別のユースケースを想定して書かれてるか、抽象化の複雑なごちゃまぜかのどっちか、いや両方の場合が多いな。自分の特定のユースケースに必要なものだけ書けば、そんなに難しい問題じゃないんだがな。

mbac32768 2025/09/21 18:32:05

現代のJSONライブラリがいかに複雑かってのは驚きだぜ。かつて“超シンプル”だったnlohmannのC++単一ヘッダーJSONライブラリですら、今や13歳、5時間前にもPRがマージされてるし、1.22億ものユニットテストがあるんだ。これでもC++で最速じゃない。最速ならsimdjsonを見てみろ。だからお前ら、自分のJSONパーサーライブラリなんて始めるな。やめとけ。45分で90%は作れても、残りの10%に1万時間かかるぞ。

flohofwoe 2025/09/21 17:51:24

でもこのライブラリより『意見がない』ものって、そうそうないだろ。キーと配列要素をイテレートして、値の型を識別して、文字列スライスを返すだけなんだから。

IshKebab 2025/09/21 17:59:53

俺にはなんか、半分しか仕事してないように感じるな。SAX“パーサー”がレキサーと大して変わらなかったのを思い出すぜ。

flohofwoe 2025/09/21 18:05:24

JSONファイルをイテレートするときに、他になにをすればいいっての?数値解析やUNICODE処理をユーザーに任せるのは、機能と見なせるよ(だって、どれだけコストをかけるか、どれだけ堅牢にするか、自分で決められるんだからね)。

IshKebab 2025/09/21 20:03:10

データをオブジェクトに抽出することだよ。SerdeやPydanticみたいなライブラリがそれをやってくれるんだ。ていうか、オリジナルのeval() JSONロードメソッドだってそうだったじゃん。

meindnoch 2025/09/21 22:58:21

そうしたら、ストリーミングする能力を失っちゃうじゃん。

IshKebab 2025/09/22 06:49:14

確かに、でも普通はデータがメモリに収まらないほど大きい場合にだけ必要で、そんな場合はそもそもJSONを使うべきじゃないんだ。(一度、JSONファイルがギガバイト単位になって、SQLiteに切り替えたらすごくうまくいったって経験があるよ。)

meindnoch 2025/09/22 08:06:14

実際、DOMスタイルのJSONパーサーは、データが利用メモリの半分より大きくなると限界が来るよ。JSONから独自のモデルオブジェクトを構築するなら、両方メモリにないとダメだからね(不要なDOM部分を段階的に破棄できるなら別だけど)。俺的には、ちゃんとしたJSONライブラリはSAXスタイルとDOMスタイルの両方を、レイヤー化して提供すべきだと思うね。

IshKebab 2025/09/22 12:31:20

>JSONから独自のモデルオブジェクトを構築したいだろうから、ある時点で両方がメモリに存在しないといけない。そうでもないよ、JSONライブラリ自体が入力ストリームできるからね。例えばserde_json::from_reader()を使えば、ファイル全体をメモリにロードせずにオブジェクトにパースできるんだ: https://docs.rs/serde_json/latest/serde_json/fn.from_reader。でも、それはちょっと学術的な話で、メモリの半分と全部って、同じくらいのレベルだよね。

forty 2025/09/21 18:35:07

JSONのパースは地雷原だぜ(2016)
https://seriot.ch/projects/parsing_json.html

modeless 2025/09/21 23:06:41

これってJSONっていうよりC++の話なんじゃね?

EasyMark 2025/09/21 19:26:33

うん、俺これ使ってるし、友達のほとんども使ってると思うよ :)

patrickmay 2025/09/21 21:11:22

>一般的にJSONパーサーライブラリは苦しみのブラックホールだよ、って俺は思う。Sexprsはここで、誰かに愛されることを願って座ってるぜ。

TheRealPomax 2025/09/21 20:46:53

「そんなに難しい問題じゃない」って言うやつは、実際にその問題を解決したことがないんだよ。

meindnoch 2025/09/22 14:29:04

それはモデルオブジェクトがserdeのstructになってる場合だけだね。モデルを特定のディスクフォーマットに縛り付けたくないから、これは望ましくないんだ。

vovavili 2025/09/21 22:35:07

ユニットテストの統計には本当に驚いたよ。JSONパースで1億2200万ものバリエーションをカバーする必要があるなんて、どんなとんでもないエッジケースがあるんだろうね?

skydhash 2025/09/21 18:12:26

Common Lispのライブラリはそこが好きだよ。ほとんどアルゴリズムに特化してて、データ構造はユーザー任せ。だから、関数を呼ぶ前にデータ構造が合ってるか確認するんだ。

kstenerud 2025/09/22 05:17:34

俺も書いたことあるけど、クラッシュレポーターで使うから、クラッシュ時に書きかけのファイルを回復できる必要があったし、エンコーダーもasync-safeじゃなきゃダメだったんだ。
https://github.com/kstenerud/KSCrash/blob/master/Sources/KSC
うん、JSONコーデック書くのは本当に最悪だよ。
だから今、同じ機能を持つasync-safeでクラッシュ耐性もあって、35倍速くてコードも少ないBONJSONコーデックに置き換えてるところ。
https://github.com/kstenerud/ksbonjson/blob/main/library/src
https://github.com/kstenerud/ksbonjson/blob/main/library/src

flohofwoe 2025/09/22 09:25:10

ほとんどの人は残りの10%の機能なんて必要ないけど、小さくて保守しやすいコードベースを重視するんだよ(nlohmannは絶対そうじゃないけどね)。

zelphirkalt 2025/09/22 09:56:17

パフォーマンスがそこまで重要じゃないなら、問題の多くは消えるよ。そうすれば、もっと良くて安全でシンプルな言語で、正しいパーサーを書く選択肢が広がるからね。C/C++でもいける。

kstenerud 2025/09/22 05:22:04

速度最適化をすればするほど、新しいエッジケースがどんどん厄介になるんだ。

typpilol 2025/09/21 19:39:02

1億2200万個のユニットテスト?何それ?

記事一覧へ

海外テックの反応まとめ
著者
海外テックの反応まとめ
暇つぶしがてらに読むだけで海外のテックニュースに詳しくなれるまとめサイトです。