From: alex Date: Fri, 31 Dec 2021 01:31:55 +0000 (-0800) Subject: ... X-Git-Url: http://git.infiniteadaptability.org/?a=commitdiff_plain;h=37fbf6633e92df72f21fd6789c776159d5df96da;p=seeder ... --- diff --git a/src/meta.c b/src/meta.c index e0ebd80..6ae4cdf 100644 --- a/src/meta.c +++ b/src/meta.c @@ -10,6 +10,8 @@ int meta_entry(const char *path, struct rss_entry *entry) { FILE *fp; ssize_t i; + memset(buf,0,META_MAX_LINE_SIZE); + if(NULL==path) { return -1; } if(NULL==entry) { return -1; } @@ -48,6 +50,13 @@ static int meta_escape(char *buf, size_t buf_size) { char *p; size_t len, left; + if((NULL==buf)||(0==buf_size)) { return -1; } + + // guarantee that buf is NULL-terminated + buf[buf_size-1] = '\0'; + + if(0==strlen(buf)) { return -1; } + const char to_escape[] = "<\\>&"; p = strpbrk(buf,to_escape); @@ -57,34 +66,32 @@ static int meta_escape(char *buf, size_t buf_size) { switch(p[0]) { case '<': - if(left<=4) { return -1; } - memmove(&(p[4]),p,len); - strcpy(p,"<"); - p += 4; + if(left<4) { return -1; } + memmove(&(p[3]),p,len); + memmove(p,"<",4); break; case '\\': if(p[1]=='n') { p[0] = '\n'; memmove(&(p[1]),&(p[2]),len); - p++; + p[len-1] = '\0'; } break; case '>': - if(left<=4) { return -1; } - memmove(&(p[4]),p,len); - strcpy(p,">"); - p += 4; + if(left<4) { return -1; } + memmove(&(p[3]),p,len); + memmove(p,">",4); break; case '&': - if(left<=5) { return -1; } - memmove(&(p[5]),p,len); - strcpy(p,"&"); - p += 5; + if(left<5) { return -1; } + memmove(&(p[4]),p,len); + memmove(p,"&",5); break; default: return -1; } + p++; p = strpbrk(p,to_escape); } @@ -145,7 +152,7 @@ static FILE *meta_search(const char *path) { p = concat(path,".meta"); if(NULL==p) { return NULL; } } else { - p = malloc(sizeof(char)*len); + p = malloc(sizeof(char)*(len+6)); // strlen(.meta)[5] + '\0' if(NULL==p) { return NULL; } strcpy(p,path); @@ -153,11 +160,19 @@ static FILE *meta_search(const char *path) { } fp = fopen(p,"r"); + free(p); return fp; } static ssize_t next_line(FILE *fp, char **key, char **value, char *buf, size_t buf_size) { - if(fgets(buf,buf_size,fp)==NULL) { return -1; } + size_t len; + + if(fgets(buf,buf_size,fp)==NULL) { return (feof(fp))?0:-1; } + + len = strlen(buf); + if(buf[len-1]=='\n') { + buf[len-1] = '\0'; + } if(meta_escape(buf,buf_size)<0) { return -1; } @@ -167,5 +182,6 @@ static ssize_t next_line(FILE *fp, char **key, char **value, char *buf, size_t b (**value) = '\0'; (*value)++; + return buf_size - strlen(*key); } diff --git a/test/unit/meta.tests.c b/test/unit/meta.tests.c index f3c1348..b64a622 100644 --- a/test/unit/meta.tests.c +++ b/test/unit/meta.tests.c @@ -8,11 +8,19 @@ char *strptime(const char *s, const char *format, struct tm *tm) { int main(); static void meta_entry_basic_test(); +static void meta_escape_basic_test(); +static void meta_escape_length_test(); static void meta_info_basic_test(); +static void meta_search_basic_test(); int main() { setup_env(); + meta_escape_basic_test(); + meta_escape_length_test(); + + meta_search_basic_test(); + meta_entry_basic_test(); meta_info_basic_test(); @@ -36,6 +44,10 @@ static void meta_entry_basic_test() { // (and as such will have invalid fields) assert(meta_entry(PREFIX,entry)==-1); + // half written entries must be free'd + rss_entry_free(entry); + assert(1==rss_entry_init(&entry)); + assert(meta_entry(TEST_FILE_1,entry)==1); assert(strcmp(entry->title,"test title")==0); @@ -47,6 +59,62 @@ static void meta_entry_basic_test() { rss_entry_free(entry); } +static void meta_escape_length_test() { + char buf[10]; + + memset(buf,0,10); + + strcpy(buf,"<"); + assert(meta_escape(buf,1)==-1); + strcpy(buf,"<"); + assert(meta_escape(buf,2)==-1); + strcpy(buf,"<"); + assert(meta_escape(buf,3)==-1); + strcpy(buf,"<"); + assert(meta_escape(buf,4)==-1); + strcpy(buf,"<"); + assert(meta_escape(buf,5)==1); + + assert(strcmp(buf,"<")==0); +} + +static void meta_escape_basic_test() { + char buf[1024]; + + memset(buf,0,1024); + + assert(meta_escape(NULL,0)==-1); + + assert(meta_escape(buf,0)==-1); + + strcpy(buf,"test"); + assert(meta_escape(buf,1024)==1); + + strcpy(buf,"test"); + assert(meta_escape(buf,4)==-1); + + strcpy(buf,">test"); + assert(meta_escape(buf,10)==1); + assert(strcmp(buf,">test")==0); + + strcpy(buf,"\\ntest"); + assert(meta_escape(buf,7)==1); + assert(strcmp(buf,"\ntest")==0); + + strcpy(buf,"&test"); + assert(meta_escape(buf,4)==-1); + strcpy(buf,"&test"); + assert(meta_escape(buf,10)==1); + assert(strcmp(buf,"&test")==0); +} + static void meta_info_basic_test() { struct rss_channel_info *info; @@ -62,6 +130,10 @@ static void meta_info_basic_test() { // (and as such will have invalid fields) assert(meta_info(TEST_FILE_1,info)==-1); + // half written values must be free'd + rss_channel_info_free(info); + assert(rss_channel_info_init(&info)==1); + assert(meta_info(PREFIX,info)==1); assert(strcmp(info->title,"TITLE")==0); @@ -72,3 +144,16 @@ static void meta_info_basic_test() { rss_channel_info_free(info); } + +static void meta_search_basic_test() { + FILE *fp; + fp = meta_search(NULL); + assert(NULL==fp); + + fp = meta_search("noasdfasdlkdsaofijasdlkfjasdklfjaslkdfj"); + assert(NULL==fp); + + fp = meta_search(TEST_FILE_3); + assert(fp!=NULL); + fclose(fp); +} diff --git a/test/unit/test_utils.h b/test/unit/test_utils.h index 1cb13a3..e09bc0f 100644 --- a/test/unit/test_utils.h +++ b/test/unit/test_utils.h @@ -30,7 +30,7 @@ #define TEST_FILE_8 PREFIX "/test.meta" #define TEST_FILE_8_CONTENTS "title=test title\nlink=https://whatisarealink.com\npubDate=Wed, 29 Dec 2021 12:21:12 +0000\ndescription=I wonder if \\n this'll properly be formatted/escaped \\>