-
Notifications
You must be signed in to change notification settings - Fork 54
Improve use of sprintf and snprintf #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
b628b89
96d3b1f
90e6b02
42666a2
599c38f
c320b45
f192e90
e199667
8edf26e
2b7442b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -201,7 +201,7 @@ int datum_logger_queue_msg(const char *func, int level, const char *format, ...) | |
| msg->calling_function[47] = 0; | ||
| msg->msg = &msg_buffer[buffer_id][msg_buf_idx[buffer_id]]; | ||
| va_start(args, format); | ||
| i = vsnprintf(msg->msg, 1023, format, args); | ||
| i = vsnprintf(msg->msg, sizeof(msg->msg), format, args); | ||
|
||
| msg->msg[i] = 0; | ||
| va_end(args); | ||
|
|
||
|
|
@@ -348,9 +348,9 @@ void * datum_logger_thread(void *ptr) { | |
| tm_info = localtime_r(&seconds, &tm_info_storage); | ||
| strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d %H:%M:%S", tm_info); | ||
| if (log_calling_function) { | ||
| j = snprintf(log_line, 1199, "%s.%03d [%44s] %s: %s\n", time_buffer, millis, msg->calling_function, level_text[msg->level], msg->msg); | ||
| j = snprintf(log_line, sizeof(log_line), "%s.%03d [%44s] %s: %s\n", time_buffer, millis, msg->calling_function, level_text[msg->level], msg->msg); | ||
| } else { | ||
| j = snprintf(log_line, 1199, "%s.%03d %s: %s\n", time_buffer, millis, level_text[msg->level], msg->msg); | ||
| j = snprintf(log_line, sizeof(log_line), "%s.%03d %s: %s\n", time_buffer, millis, level_text[msg->level], msg->msg); | ||
| } | ||
| log_line[1199] = 0; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should drop this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because we set NUL at 1199 anyway? We can. I just wanted to reduce relying on hardcoded lengths and make the code use defined char arrays sizes and recommended ways to call the "snprintf family". What do you think? |
||
|
|
||
|
|
@@ -390,8 +390,7 @@ void * datum_logger_thread(void *ptr) { | |
|
|
||
| tm_info = localtime_r(&log_file_opened, &tm_info_storage); | ||
| strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d", tm_info); | ||
| snprintf(log_line, 1199, "%s.%s", log_file, time_buffer); | ||
| log_line[1199] = 0; | ||
| snprintf(log_line, sizeof(log_line), "%s.%s", log_file, time_buffer); | ||
|
|
||
| fclose(log_handle); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -690,7 +690,7 @@ void datum_stratum_v1_socket_thread_loop(T_DATUM_THREAD_DATA *my) { | |
| void send_error_to_client(T_DATUM_CLIENT_DATA *c, uint64_t id, char *e) { | ||
| // "e" must be valid JSON string | ||
| char s[1024]; | ||
| snprintf(s, 1023, "{\"error\":%s,\"id\":%"PRIu64",\"result\":null}\n", e, id); | ||
| snprintf(s, sizeof(s), "{\"error\":%s,\"id\":%"PRIu64",\"result\":null}\n", e, id); | ||
| datum_socket_send_string_to_client(c, s); | ||
| } | ||
|
|
||
|
|
@@ -1283,7 +1283,7 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj | |
| } | ||
|
|
||
| char s[256]; | ||
| snprintf(s, 255, "{\"error\":null,\"id\":%"PRIu64",\"result\":true}\n", id); | ||
| snprintf(s, sizeof(s), "{\"error\":null,\"id\":%"PRIu64",\"result\":true}\n", id); | ||
| datum_socket_send_string_to_client(c, s); | ||
|
|
||
| // update connection totals | ||
|
|
@@ -1370,15 +1370,15 @@ int client_mining_configure(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_ | |
| } | ||
| } | ||
|
|
||
| i = snprintf(sa, 1023, "{\"error\":null,\"id\":%"PRIu64",\"result\":{", id); | ||
| i = snprintf(sa, sizeof(sa), "{\"error\":null,\"id\":%"PRIu64",\"result\":{", id); | ||
| if (new_vroll) { | ||
| i+= snprintf(&sa[i], 1023-i, "\"version-rolling\":true,\"version-rolling.mask\":\"%08x\"", m->extension_version_rolling_mask); | ||
| i+= snprintf(&sa[i], sizeof(sa)-i, "\"version-rolling\":true,\"version-rolling.mask\":\"%08x\"", m->extension_version_rolling_mask); | ||
| } | ||
| if (new_mdiff) { | ||
| // we don't currently support miner specified minimum difficulty. | ||
| i+= snprintf(&sa[i], 1023-i, ",\"minimum-difficulty\":false"); | ||
| i+= snprintf(&sa[i], sizeof(sa)-i, ",\"minimum-difficulty\":false"); | ||
| } | ||
| i+= snprintf(&sa[i], 1023-i, "}}\n"); | ||
| i+= snprintf(&sa[i], sizeof(sa)-i, "}}\n"); | ||
|
|
||
| datum_socket_send_string_to_client(c, sa); | ||
|
|
||
|
|
@@ -1406,10 +1406,10 @@ int client_mining_authorize(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_ | |
| } | ||
| } | ||
|
|
||
| strncpy(m->last_auth_username, username_s, 191); | ||
| m->last_auth_username[191] = 0; | ||
| strncpy(m->last_auth_username, username_s, sizeof(m->last_auth_username) - 1); | ||
| m->last_auth_username[sizeof(m->last_auth_username)-1] = 0; | ||
|
|
||
| snprintf(s, 255, "{\"error\":null,\"id\":%"PRIu64",\"result\":true}\n", id); | ||
| snprintf(s, sizeof(s), "{\"error\":null,\"id\":%"PRIu64",\"result\":true}\n", id); | ||
| datum_socket_send_string_to_client(c, s); | ||
|
|
||
| m->authorized = true; | ||
|
|
@@ -1523,12 +1523,12 @@ int send_mining_notify(T_DATUM_CLIENT_DATA *c, bool clean, bool quickdiff, bool | |
| // new block work always is just a blank coinbase, for now | ||
|
|
||
| if (quickdiff) { | ||
| snprintf(s, 511, "\"Q%s%2.2x\",\"%s\",\"", j->job_id, cbselect, j->prevhash); | ||
| snprintf(s, sizeof(s), "\"Q%s%2.2x\",\"%s\",\"", j->job_id, cbselect, j->prevhash); | ||
| } else { | ||
| if (!new_block) { | ||
| snprintf(s, 511, "\"%s%2.2x\",\"%s\",\"", j->job_id, cbselect, j->prevhash); | ||
| snprintf(s, sizeof(s), "\"%s%2.2x\",\"%s\",\"", j->job_id, cbselect, j->prevhash); | ||
| } else { | ||
| snprintf(s, 511, "\"N%s%2.2x\",\"%s\",\"", j->job_id, 255, j->prevhash); // empty coinbase for new block | ||
| snprintf(s, sizeof(s), "\"N%s%2.2x\",\"%s\",\"", j->job_id, 255, j->prevhash); // empty coinbase for new block | ||
| cb = &j->subsidy_only_coinbase; | ||
| } | ||
| } | ||
|
|
@@ -1571,7 +1571,7 @@ int send_mining_notify(T_DATUM_CLIENT_DATA *c, bool clean, bool quickdiff, bool | |
| // send empty merkle leafs | ||
| datum_socket_send_string_to_client(c, "[]"); | ||
| } | ||
| snprintf(s, 511, ",\"%s\",\"%s\",\"%s\",", j->version, j->nbits, j->ntime); | ||
| snprintf(s, sizeof(s), ",\"%s\",\"%s\",\"%s\",", j->version, j->nbits, j->ntime); | ||
| datum_socket_send_string_to_client(c, s); | ||
|
|
||
| // bunch of reasons we may need to discard old work | ||
|
|
@@ -1594,7 +1594,7 @@ int send_mining_set_difficulty(T_DATUM_CLIENT_DATA *c) { | |
| m->current_diff = datum_config.stratum_v1_vardiff_min; | ||
| } | ||
|
|
||
| snprintf(s, 255, "{\"id\":null,\"method\":\"mining.set_difficulty\",\"params\":[%"PRIu64"]}\n", (uint64_t)m->current_diff); | ||
| snprintf(s, sizeof(s), "{\"id\":null,\"method\":\"mining.set_difficulty\",\"params\":[%"PRIu64"]}\n", (uint64_t)m->current_diff); | ||
| datum_socket_send_string_to_client(c, s); | ||
|
|
||
| m->last_sent_diff = m->current_diff; | ||
|
|
@@ -1712,7 +1712,7 @@ int client_mining_subscribe(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_ | |
| m->sid_inv = ((sid>>24)&0xff) | (((sid>>16)&0xff)<<8) | (((sid>>8)&0xff)<<16) | ((sid&0xff)<<24); | ||
|
|
||
| // tell them about all of this | ||
| snprintf(s, 1023, "{\"error\":null,\"id\":%"PRIu64",\"result\":[[[\"mining.notify\",\"%8.8x1\"],[\"mining.set_difficulty\",\"%8.8x2\"]],\"%8.8x\",8]}\n", id, sid, sid, sid); | ||
| snprintf(s, sizeof(s), "{\"error\":null,\"id\":%"PRIu64",\"result\":[[[\"mining.notify\",\"%8.8x1\"],[\"mining.set_difficulty\",\"%8.8x2\"]],\"%8.8x\",8]}\n", id, sid, sid, sid); | ||
| datum_socket_send_string_to_client(c, s); | ||
|
|
||
| // send them their current difficulty before sending a job | ||
|
|
@@ -1967,14 +1967,14 @@ void update_stratum_job(T_DATUM_TEMPLATE_DATA *block_template, bool new_block, i | |
| } | ||
| s->prevhash[64] = 0; | ||
|
|
||
| snprintf(s->version, 9, "%8.8x", block_template->version); | ||
| snprintf(s->version, sizeof(s->version), "%8.8x", block_template->version); | ||
| s->version_uint = block_template->version; | ||
| strncpy(s->nbits, block_template->bits, 9); | ||
| strncpy(s->nbits, block_template->bits, sizeof(s->nbits) - 1); | ||
|
|
||
| // TODO: Should we use local time, and just verify is valid for the block? | ||
| // Perhaps as an option. | ||
| // The template's time is 100% safe, so we'll use that for now. | ||
| snprintf(s->ntime, 9, "%8.8llx", (unsigned long long)block_template->curtime); | ||
| snprintf(s->ntime, sizeof(s->ntime), "%8.8llx", (unsigned long long)block_template->curtime); | ||
|
|
||
| // Set the coinbase value of this job based on the template | ||
| s->coinbase_value = block_template->coinbasevalue; | ||
|
|
@@ -2054,7 +2054,7 @@ void update_stratum_job(T_DATUM_TEMPLATE_DATA *block_template, bool new_block, i | |
| } | ||
|
|
||
| s->global_index = global_latest_stratum_job_index; | ||
| snprintf(s->job_id, 23, "%8.8x%2.2x%4.4x", (uint32_t)time(NULL), (uint8_t)stratum_job_next, (uint16_t)s->global_index ^ STRATUM_JOB_INDEX_XOR); | ||
| snprintf(s->job_id, sizeof(s->job_id), "%8.8x%2.2x%4.4x", (uint32_t)time(NULL), (uint8_t)stratum_job_next, (uint16_t)s->global_index ^ STRATUM_JOB_INDEX_XOR); | ||
|
|
||
| global_cur_stratum_jobs[global_latest_stratum_job_index] = s; | ||
| pthread_rwlock_unlock(&stratum_global_job_ptr_lock); | ||
|
|
@@ -2071,7 +2071,7 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t | |
| size_t i; | ||
| json_t *r; | ||
| CURL *tcurl; | ||
| char userpass[512]; | ||
| char userpass[1024]; | ||
|
||
| int ret = 0; | ||
| bool free_submitblock_req = false; | ||
| char *s = NULL; | ||
|
|
@@ -2140,8 +2140,7 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t | |
| if (datum_config.mining_save_submitblocks_dir[0] != 0) { | ||
| // save the block submission to a file named by the block's hash | ||
| FILE *f; | ||
| snprintf(userpass, 511, "%s/datum_submitblock_%s.json", datum_config.mining_save_submitblocks_dir, block_hash_hex); | ||
| userpass[511] = 0; | ||
| snprintf(userpass, sizeof(userpass), "%s/datum_submitblock_%s.json", datum_config.mining_save_submitblocks_dir, block_hash_hex); | ||
| f = fopen(userpass, "w"); | ||
| if (!f) { | ||
| DLOG_ERROR("Could not open %s for writing submitblock record to disk: %s!", userpass, strerror(errno)); | ||
|
|
@@ -2162,7 +2161,7 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t | |
| return 0; | ||
| } | ||
|
|
||
| sprintf(userpass, "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword); | ||
| snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword); | ||
|
|
||
| // make the call! | ||
| r = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, submitblock_req); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,10 +55,8 @@ void preciousblock(CURL *curl, char *blockhash) { | |
| char userpass[1024]; | ||
|
||
|
|
||
| // TODO: Move these types of things to the conf file | ||
| snprintf(userpass, 1023, "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword); | ||
| userpass[1023] = 0; | ||
|
|
||
| sprintf(rpc_data,"{\"method\":\"preciousblock\",\"params\":[\"%s\"],\"id\":1}",blockhash); | ||
| snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword); | ||
| snprintf(rpc_data, sizeof(rpc_data), "{\"method\":\"preciousblock\",\"params\":[\"%s\"],\"id\":1}", blockhash); | ||
| json = json_rpc_call(curl, datum_config.bitcoind_rpcurl, userpass, rpc_data); | ||
| if (!json) return; | ||
|
|
||
|
|
@@ -72,8 +70,7 @@ void datum_submitblock_doit(CURL *tcurl, char *url, const char *submitblock_req, | |
| char *s = NULL; | ||
| // TODO: Move these types of things to the conf file | ||
| if (!url) { | ||
| snprintf(userpass, 1023, "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword); | ||
| userpass[1023] = 0; | ||
| snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword); | ||
|
|
||
| r = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, submitblock_req); | ||
| } else { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each of user and pass accept up to 1023 bytes, so maybe for consistency this should be
(1023 * 2) + 2?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There' further inconsistency.
datum_conf.h says:
datum_conf.c has max_string_length set to
128and it does truncate to 128so maximum userpass would be even less: 127*2+2, but I suggest to focus this one on the userpass and snprintf bits and leave aligning that with datum_conf.c and datum_conf.h in a seprate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, I was mixing it up with pool_host/pubkey.
Just be careful with the one case it's reused for a file path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from the path reuse case. How about we populate the
userpassonce at startup, and access as a config variable, instead of reconstructing it all the time in 5 files?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Next commit shows what I meant. Do the userpass thing just one time, keep it global, similarly to how is set once
datum_protocol_global_timeout_ms. This eliminates all those multiple snprintf()sI've also thrown in some other goodies:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this fine?