aboutsummaryrefslogtreecommitdiffstats
path: root/g10/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/misc.c')
-rw-r--r--g10/misc.c147
1 files changed, 79 insertions, 68 deletions
diff --git a/g10/misc.c b/g10/misc.c
index 0588965b2..4316d8f01 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -38,6 +38,7 @@
#endif
#include "util.h"
#include "main.h"
+#include "photoid.h"
#include "options.h"
#include "i18n.h"
@@ -439,55 +440,56 @@ idea_cipher_warn(int show)
}
}
-/* The largest string we have an expando for. */
-#define LARGEST_EXPANDO (MAX_FINGERPRINT_LEN*2)
-
/* Expand %-strings. Returns a string which must be m_freed. Returns
NULL if the string cannot be expanded (too large). */
char *
-pct_expando(const char *string,PKT_public_key *pk)
+pct_expando(const char *string,struct expando_args *args)
{
const char *ch=string;
- int idx=0,maxlen;
+ int idx=0,maxlen=0,done=0;
u32 keyid[2]={0,0};
- char *ret;
-
- keyid_from_pk(pk,keyid);
+ char *ret=NULL;
- maxlen=LARGEST_EXPANDO*2;
- ret=m_alloc(maxlen+1); /* one more to leave room for the trailing \0 */
-
- ret[0]='\0';
+ if(args->pk)
+ keyid_from_pk(args->pk,keyid);
while(*ch!='\0')
{
- /* 8192 is way bigger than we'll need here */
- if(maxlen-idx<LARGEST_EXPANDO && maxlen<8192)
+ char *str=NULL;
+
+ if(!done)
{
- maxlen+=LARGEST_EXPANDO*2;
- ret=m_realloc(ret,maxlen+1);
+ /* 8192 is way bigger than we'll need here */
+ if(maxlen>=8192)
+ goto fail;
+
+ maxlen+=1024;
+ ret=m_realloc(ret,maxlen);
}
+ done=0;
+
if(*ch=='%')
{
- ch++;
-
- switch(*ch)
+ switch(*(ch+1))
{
case 'k': /* short key id */
- if(idx+8>maxlen)
- goto fail;
-
- sprintf(&ret[idx],"%08lX",(ulong)keyid[1]);
- idx+=8;
+ if(idx+8<maxlen)
+ {
+ sprintf(&ret[idx],"%08lX",(ulong)keyid[1]);
+ idx+=8;
+ done=1;
+ }
break;
case 'K': /* long key id */
- if(idx+16>maxlen)
- goto fail;
-
- sprintf(&ret[idx],"%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
- idx+=16;
+ if(idx+16<maxlen)
+ {
+ sprintf(&ret[idx],"%08lX%08lX",
+ (ulong)keyid[0],(ulong)keyid[1]);
+ idx+=16;
+ done=1;
+ }
break;
case 'f': /* fingerprint */
@@ -496,43 +498,46 @@ pct_expando(const char *string,PKT_public_key *pk)
size_t len;
int i;
- fingerprint_from_pk(pk,array,&len);
-
- if(idx+(len*2)>maxlen)
- goto fail;
+ if(args->pk)
+ fingerprint_from_pk(args->pk,array,&len);
+ else
+ memset(array,0,MAX_FINGERPRINT_LEN);
- for(i=0;i<len;i++)
+ if(idx+(len*2)<maxlen)
{
- sprintf(&ret[idx],"%02X",array[i]);
- idx+=2;
+ for(i=0;i<len;i++)
+ {
+ sprintf(&ret[idx],"%02X",array[i]);
+ idx+=2;
+ }
+ done=1;
}
}
break;
- /* photo types. For now, it's always jpeg so this is
- easy! */
- case 't':
- if(idx+3>maxlen)
- goto fail;
+ case 't': /* e.g. "jpg" */
+ str=image_type_to_string(args->imagetype,1);
+ /* fall through */
- strcpy(&ret[idx],"jpg");
- idx+=3;
- break;
-
- case 'T':
- if(idx+10>maxlen)
- goto fail;
+ case 'T': /* e.g. "image/jpeg" */
+ if(str==NULL)
+ str=image_type_to_string(args->imagetype,2);
- strcpy(&ret[idx],"image/jpeg");
- idx+=10;
+ if(idx+strlen(str)<maxlen)
+ {
+ strcpy(&ret[idx],str);
+ idx+=strlen(str);
+ done=1;
+ }
break;
case '%':
- if(idx+1>maxlen)
- goto fail;
-
- ret[idx++]='%';
- ret[idx]='\0';
+ if(idx+1<maxlen)
+ {
+ ret[idx++]='%';
+ ret[idx]='\0';
+ done=1;
+ }
break;
/* Any unknown %-keys (like %i, %o, %I, and %O) are
@@ -541,25 +546,31 @@ pct_expando(const char *string,PKT_public_key *pk)
string is a '%' - the terminating \0 will end up here
and properly terminate the string. */
default:
- if(idx+2>maxlen)
- goto fail;
-
- ret[idx++]='%';
- ret[idx++]=*ch;
- ret[idx]='\0';
+ if(idx+2<maxlen)
+ {
+ ret[idx++]='%';
+ ret[idx++]=*(ch+1);
+ ret[idx]='\0';
+ done=1;
+ }
break;
- }
+ }
+
+ if(done)
+ ch++;
}
else
{
- if(idx+1>maxlen)
- goto fail;
-
- ret[idx++]=*ch;
- ret[idx]='\0';
+ if(idx+1<maxlen)
+ {
+ ret[idx++]=*ch;
+ ret[idx]='\0';
+ done=1;
+ }
}
- ch++;
+ if(done)
+ ch++;
}
return ret;