Skip to content

Commit

Permalink
set line length for armored output #1099
Browse files Browse the repository at this point in the history
  • Loading branch information
rrrooommmaaa committed Jul 2, 2020
1 parent edc692c commit 06782ba
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 5 deletions.
8 changes: 8 additions & 0 deletions include/rnp/rnp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,14 @@ RNP_API rnp_result_t rnp_identifier_iterator_destroy(rnp_identifier_iterator_t i
*/
RNP_API rnp_result_t rnp_output_pipe(rnp_input_t input, rnp_output_t output);

/** Set line length for armored output
*
* @param output stream to configure
* @param llen line length in characters [16..76]
* @return RNP_SUCCESS on success, or any other value on error
*/
RNP_API rnp_result_t rnp_output_armor_set_line_length(rnp_output_t output, size_t llen);

#if defined(__cplusplus)
}

Expand Down
9 changes: 9 additions & 0 deletions src/lib/rnp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7223,3 +7223,12 @@ rnp_output_pipe(rnp_input_t input, rnp_output_t output)
output->keep = !ret;
return ret;
}

rnp_result_t
rnp_output_armor_set_line_length(rnp_output_t output, size_t llen)
{
if (!output || !llen) {
return RNP_ERROR_BAD_PARAMETERS;
}
return armored_dst_set_line_length(&output->dst, llen);
}
30 changes: 26 additions & 4 deletions src/librepgp/stream-armor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include "types.h"

#define ARMORED_BLOCK_SIZE (4096)
#define ARMORED_MIN_LINE_LENGTH (16)
#define ARMORED_MAX_LINE_LENGTH (76)

typedef struct pgp_source_armored_param_t {
pgp_source_t * readsrc; /* source to read from */
Expand Down Expand Up @@ -789,10 +791,12 @@ armored_dst_write(pgp_dest_t *dst, const void *buf, size_t len)
}
}

/* this version prints whole chunks, so rounding down to the closest 4 */
auto adjusted_llen = param->llen & ~3;
/* number of input bytes to form a whole line of output, param->llen / 4 * 3 */
inllen = (param->llen >> 2) + (param->llen >> 1);
inllen = (adjusted_llen >> 2) + (adjusted_llen >> 1);
/* pointer to the last full line space in encbuf */
enclast = encbuf + sizeof(encbuf) - param->llen - 2;
enclast = encbuf + sizeof(encbuf) - adjusted_llen - 2;

/* processing line chunks, this is the main performance-hitting cycle */
while (bufptr + 3 <= bufend) {
Expand All @@ -802,8 +806,8 @@ armored_dst_write(pgp_dest_t *dst, const void *buf, size_t len)
encptr = encbuf;
}
/* setup length of the input to process in this iteration */
inlend =
param->lout == 0 ? bufptr + inllen : bufptr + ((param->llen - param->lout) >> 2) * 3;
inlend = param->lout == 0 ? bufptr + inllen :
bufptr + ((adjusted_llen - param->lout) >> 2) * 3;
if (inlend > bufend) {
/* no enough input for the full line */
inlend = bufptr + (bufend - bufptr) / 3 * 3;
Expand Down Expand Up @@ -948,6 +952,24 @@ init_armored_dst(pgp_dest_t *dst, pgp_dest_t *writedst, pgp_armored_msg_t msgtyp
return ret;
}

bool
is_armored_dest(pgp_dest_t *dst)
{
return dst->type == PGP_STREAM_ARMORED;
}

rnp_result_t
armored_dst_set_line_length(pgp_dest_t *dst, size_t llen)
{
if (!dst || llen < ARMORED_MIN_LINE_LENGTH || llen > ARMORED_MAX_LINE_LENGTH ||
!dst->param || !is_armored_dest(dst)) {
return RNP_ERROR_BAD_PARAMETERS;
}
auto param = (pgp_dest_armored_param_t *) dst->param;
param->llen = llen;
return RNP_SUCCESS;
}

bool
is_armored_source(pgp_source_t *src)
{
Expand Down
16 changes: 15 additions & 1 deletion src/librepgp/stream-armor.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, [Ribose Inc](https://www.ribose.com).
* Copyright (c) 2017-2020, [Ribose Inc](https://www.ribose.com).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
Expand Down Expand Up @@ -88,10 +88,24 @@ pgp_armored_msg_t rnp_armored_get_type(pgp_source_t *src);
**/
bool is_armored_source(pgp_source_t *src);

/* @brief Check whether destination is armored
* @param dest initialized destination
* @return true if destination is armored or false otherwise
**/
bool is_armored_dest(pgp_dest_t *dst);

/* @brief Check whether source is cleartext signed
* @param src initialized source with some data
* @return true if source could be a cleartext signed data or false otherwise
**/
bool is_cleartext_source(pgp_source_t *src);

/** Set line length for armoring
*
* @param dst initialized dest to write armored data to
* @param llen line length in characters
* @return RNP_SUCCESS on success, or any other value on error
*/
rnp_result_t armored_dst_set_line_length(pgp_dest_t *dst, size_t llen);

#endif
Loading

0 comments on commit 06782ba

Please sign in to comment.