Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine. 2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 : /* See LICENSE for licensing information */ 5 : 6 : /** 7 : * \file recommend_pkg.c 8 : * \brief Code related to the recommended-packages subsystem. 9 : * 10 : * Currently unused. 11 : **/ 12 : 13 : #include "core/or/or.h" 14 : #include "feature/dirauth/recommend_pkg.h" 15 : 16 : /** Return true iff <b>line</b> is a valid RecommendedPackages line. 17 : */ 18 : /* 19 : The grammar is: 20 : 21 : "package" SP PACKAGENAME SP VERSION SP URL SP DIGESTS NL 22 : 23 : PACKAGENAME = NONSPACE 24 : VERSION = NONSPACE 25 : URL = NONSPACE 26 : DIGESTS = DIGEST | DIGESTS SP DIGEST 27 : DIGEST = DIGESTTYPE "=" DIGESTVAL 28 : 29 : NONSPACE = one or more non-space printing characters 30 : 31 : DIGESTVAL = DIGESTTYPE = one or more non-=, non-" " characters. 32 : 33 : SP = " " 34 : NL = a newline 35 : 36 : */ 37 : int 38 66 : validate_recommended_package_line(const char *line) 39 : { 40 66 : const char *cp = line; 41 : 42 : #define WORD() \ 43 : do { \ 44 : if (*cp == ' ') \ 45 : return 0; \ 46 : cp = strchr(cp, ' '); \ 47 : if (!cp) \ 48 : return 0; \ 49 : } while (0) 50 : 51 66 : WORD(); /* skip packagename */ 52 63 : ++cp; 53 63 : WORD(); /* skip version */ 54 58 : ++cp; 55 58 : WORD(); /* Skip URL */ 56 54 : ++cp; 57 : 58 : /* Skip digesttype=digestval + */ 59 54 : int n_entries = 0; 60 72 : while (1) { 61 63 : const char *start_of_word = cp; 62 63 : const char *end_of_word = strchr(cp, ' '); 63 63 : if (! end_of_word) 64 54 : end_of_word = cp + strlen(cp); 65 : 66 63 : if (start_of_word == end_of_word) 67 : return 0; 68 : 69 61 : const char *eq = memchr(start_of_word, '=', end_of_word - start_of_word); 70 : 71 61 : if (!eq) 72 : return 0; 73 59 : if (eq == start_of_word) 74 : return 0; 75 59 : if (eq == end_of_word - 1) 76 : return 0; 77 59 : if (memchr(eq+1, '=', end_of_word - (eq+1))) 78 : return 0; 79 : 80 58 : ++n_entries; 81 58 : if (0 == *end_of_word) 82 : break; 83 : 84 9 : cp = end_of_word + 1; 85 : } 86 : 87 : /* If we reach this point, we have at least 1 entry. */ 88 : tor_assert(n_entries > 0); 89 : return 1; 90 : }