bug: Incorrect value substitution in executeSet causes text corruption (manual escaping instead of parameter binding)
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 48/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- android, java, sqlite, typescript
- 領域
- databases, mobile-dev
調査の方向性
android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java から開始し、multipleRowsStatement とそこからの prepareSQL() の呼び出しに重点を置きます。提供されたカレンダーテキストを使って executeSet を再現し、その後、値が SQLite に到達するまでの流れを追跡します。挿入および取得された文字列がキャリッジリターンをバイト単位で保持し、利用可能であれば関連する動作がプロジェクト既存のテストでカバーされていれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Plugin version:
7.0.2
Platform(s):
Android, Web
Current behavior:
Currently, the values sent in an executeSet statement are replaced by the library after manually escaping the values using DatabaseUtils.sqlEscapeString. This makes it so the inserted string is not the same as the one retrieved, potentially damaging data.
Expected behavior:
Inserted strings are byte-by-byte identical when inserted in the SQLite database.
Steps to reproduce:
Use the executeSet method with query and values like the following:
const statement = "INSERT INTO calendars (year, content) VALUES (?, ?);";
const values = [
[2020, "BEGIN:VCALENDAR\r\nVERSION:2.0...END:VCALENDAR\r\n"],
[2021, "BEGIN:VCALENDAR\r\nVERSION:2.0...END:VCALENDAR\r\n"]
];
const set = [{ statement, values }];
const res = await this.sqlitePlugin!.executeSet({
database: dbName,
set,
returnMode,
transaction: true,
readonly: false
});
The statement will be executed without hinting at any issues, but the values written and returned (either from this query when using returnMode = "all" and adding "RETURNING *" to the statement, or by a select at a later moment) will lack the carriage returns, making the calendar text out of spec and impossible to parse and recover.
Related code:
The method "multipleRowsStatement" performs the substitution: android\src\main\java\com\getcapacitor\community\database\sqlite\SQLite\Database.java
public JSObject multipleRowsStatement(String statement, JSONArray valuesJson, String returnMode) throws Exception {
StringBuilder sqlBuilder = new StringBuilder();
try {
for (int j = 0; j < valuesJson.length(); j++) {
JSONArray innerArray = valuesJson.getJSONArray(j);
StringBuilder innerSqlBuilder = new StringBuilder();
for (int k = 0; k < innerArray.length(); k++) {
Object innerElement = innerArray.get(k);
String elementValue = "";
if (innerElement instanceof String) {
elementValue = DatabaseUtils.sqlEscapeString((String) innerElement);
} else {
elementValue = String.valueOf(innerElement);
}
innerSqlBuilder.append(elementValue);
if (k < innerArray.length() - 1) {
innerSqlBuilder.append(",");
}
}
sqlBuilder.append("(").append(innerSqlBuilder.toString()).append(")");
if (j < valuesJson.length() - 1) {
sqlBuilder.append(",");
}
}
String finalSql = replacePlaceholders(statement, sqlBuilder.toString());
JSObject respSet = prepareSQL(finalSql, new ArrayList<>(), false, returnMode);
return respSet;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
Other information:
I have reproduced and debugged the issue in Android Studio.
A proposed fix will be provided in an associated Draft PR.
The recommended approach is to pass the parameter values as an ArrayList to prepareSQL() and let SQLite handle binding, rather than manually constructing SQL strings.
Capacitor doctor:
Capacitor Doctor
Latest Dependencies:
@capacitor/cli: 7.4.4
@capacitor/core: 7.4.4
@capacitor/android: 7.4.4
@capacitor/ios: 7.4.4
Installed Dependencies:
@capacitor/core: 7.4.3
@capacitor/android: 7.4.3
@capacitor/ios: 7.4.3
@capacitor/cli: 7.4.3
[success] Android looking great! 👌
[error] Xcode is not installed
- 主要言語
- Swift
- スター
- 661
- フォーク
- 158
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
capacitor-community/sqlite のほかの issue
-
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
capacitor-community/sqlite#700 · コメント 1 件 · リアクション 1 件 ·
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
capacitor-community/sqlite#693 · リアクション 7 件 ·
-
bug/fix needs: triage
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
capacitor-community/sqlite#690 ·
-
feature needs: triage
難易度 3/5 1〜2日 初心者へのやさしさ 55/100
capacitor-community/sqlite#689 ·
-
bug/fix needs: triage
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
capacitor-community/sqlite#685 ·
capacitor-community/sqlite の issue をすべて見る
似ている issue
-
area:dictation bug good first issue P2
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
uttrflow/uttrflow-swift#1956 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
callstackincubator/appduct#129 ·
メンテナーはふだん 1 日以内に返信
-
clawsweeper:not-repro-on-main impact:ux-friction issue-rating: 🦪 silver shellfish P2
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
steipete/CodexBar#4040 · コメント 1 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
mozilla-mobile/firefox-ios#35827 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
solana-foundation/pay-kit#341 ·
メンテナーはふだん 1 日以内に返信