bkpr incomestmt: properly escape things for the CSVs

First off, when we pull data out of JSON, unescape it so we don't end up
with extraneous escapes in our bookkeeping data. I promise, it's worth
it.

Then, when we print descriptions out to the csvs, we gotta wrap
everything in quotes... but also we have to change all the double-quotes
to singles so that adding the quotes doesn't do anything untoward.

We also just pass it thru json_escape to get rid of linebreaks etc.

Note that in the tests we do a byte comparison instead of converting the
CSV dumps to strings because python will escape the strings on
conversion...
This commit is contained in:
niftynei
2022-07-19 17:04:40 +09:30
committed by Rusty Russell
parent 5146baa00b
commit e5d3ce3b1f
3 changed files with 45 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
#include "config.h"
#include <ccan/array_size/array_size.h>
#include <ccan/cast/cast.h>
#include <ccan/json_escape/json_escape.h>
#include <ccan/tal/str/str.h>
#include <ccan/tal/tal.h>
#include <ccan/time/time.h>
@@ -1178,7 +1179,9 @@ listinvoice_done(struct command *cmd, const char *buf,
if (desc) {
db_begin_transaction(db);
add_payment_hash_desc(db, payment_hash, desc);
add_payment_hash_desc(db, payment_hash,
json_escape_unescape(cmd,
(struct json_escape *)desc));
db_commit_transaction(db);
} else
plugin_log(cmd->plugin, LOG_DBG,

View File

@@ -105,6 +105,26 @@ static struct income_event *onchainfee_to_income(const tal_t *ctx,
return inc;
}
/* CSVs don't like ',' in the middle. We short circuit this
* by wrapping the desc in double-quotes ("). But what if
* there's already double-quotes? Well we swap these to
* single-quotes (') and then use the json_escape function */
static char *csv_safe_str(const tal_t *ctx, char *input TAKES)
{
struct json_escape *esc;
char *dupe;
/* Update the double-quotes in place */
dupe = tal_strdup(ctx, input);
for (size_t i = 0; dupe[i] != '\0'; i++) {
if (dupe[i] == '"')
dupe[i] = '\'';
}
esc = json_escape(ctx, dupe);
return tal_fmt(ctx, "\"%s\"", esc->s);
}
static struct income_event *maybe_chain_income(const tal_t *ctx,
struct db *db,
struct account *acct,
@@ -589,7 +609,7 @@ static void koinly_entry(const tal_t *ctx, FILE *csvf, struct income_event *ev)
/* Description */
if (ev->desc)
fprintf(csvf, "%s", ev->desc);
fprintf(csvf, "%s", csv_safe_str(ev, ev->desc));
fprintf(csvf, ",");
/* TxHash */
@@ -733,7 +753,7 @@ static void harmony_entry(const tal_t *ctx, FILE *csvf, struct income_event *ev)
fprintf(csvf, ",");
/* ",Note" description (may be NULL) */
fprintf(csvf, "%s", ev->desc ? ev->desc : "");
fprintf(csvf, "%s", ev->desc ? csv_safe_str(ev, ev->desc) : "");
}
static void quickbooks_header(FILE *csvf)
@@ -766,7 +786,7 @@ static void quickbooks_entry(const tal_t *ctx, FILE *csvf, struct income_event *
/* Description */
fprintf(csvf, "%s (%s) %s: %s",
ev->tag, ev->acct_name, ev->currency,
ev->desc ? ev->desc : "no desc");
ev->desc ? csv_safe_str(ev, ev->desc) : "no desc");
fprintf(csvf, ",");
/* Credit */