/* Match host names according to RFC 2818 rules */ int gitno__match_host(const char *pattern, const char *host) { for (;;) { char c = git__tolower(*pattern++); if (c == '\0') return *host ? -1 : 0; if (c == '*') { c = *pattern; /* '*' at the end matches everything left */ if (c == '\0') return 0; /* * We've found a pattern, so move towards the next matching * char. The '.' is handled specially because wildcards aren't * allowed to cross subdomains. */ while(*host) { char h = git__tolower(*host); if (c == h) return gitno__match_host(pattern, host++); if (h == '.') return gitno__match_host(pattern, host); host++; } return -1; } if (c != git__tolower(*host++)) return -1; } return -1; }
static int read_variable_cb( git_config_parser *reader, const char *current_section, const char *var_name, const char *var_value, const char *line, size_t line_len, void *payload) { config_memory_parse_data *parse_data = (config_memory_parse_data *) payload; git_buf buf = GIT_BUF_INIT; git_config_entry *entry; const char *c; int result; GIT_UNUSED(reader); GIT_UNUSED(line); GIT_UNUSED(line_len); if (current_section) { /* TODO: Once warnings land, we should likely warn * here. Git appears to warn in most cases if it sees * un-namespaced config options. */ git_buf_puts(&buf, current_section); git_buf_putc(&buf, '.'); } for (c = var_name; *c; c++) git_buf_putc(&buf, git__tolower(*c)); if (git_buf_oom(&buf)) return -1; entry = git__calloc(1, sizeof(git_config_entry)); GITERR_CHECK_ALLOC(entry); entry->name = git_buf_detach(&buf); entry->value = var_value ? git__strdup(var_value) : NULL; entry->level = parse_data->level; entry->include_depth = 0; if ((result = git_config_entries_append(parse_data->entries, entry)) < 0) return result; return result; }
static int32_t next_hfs_char(const char **in, size_t *len) { while (*len) { int32_t codepoint; int cp_len = git__utf8_iterate((const uint8_t *)(*in), (int)(*len), &codepoint); if (cp_len < 0) return -1; (*in) += cp_len; (*len) -= cp_len; /* these code points are ignored completely */ switch (codepoint) { case 0x200c: /* ZERO WIDTH NON-JOINER */ case 0x200d: /* ZERO WIDTH JOINER */ case 0x200e: /* LEFT-TO-RIGHT MARK */ case 0x200f: /* RIGHT-TO-LEFT MARK */ case 0x202a: /* LEFT-TO-RIGHT EMBEDDING */ case 0x202b: /* RIGHT-TO-LEFT EMBEDDING */ case 0x202c: /* POP DIRECTIONAL FORMATTING */ case 0x202d: /* LEFT-TO-RIGHT OVERRIDE */ case 0x202e: /* RIGHT-TO-LEFT OVERRIDE */ case 0x206a: /* INHIBIT SYMMETRIC SWAPPING */ case 0x206b: /* ACTIVATE SYMMETRIC SWAPPING */ case 0x206c: /* INHIBIT ARABIC FORM SHAPING */ case 0x206d: /* ACTIVATE ARABIC FORM SHAPING */ case 0x206e: /* NATIONAL DIGIT SHAPES */ case 0x206f: /* NOMINAL DIGIT SHAPES */ case 0xfeff: /* ZERO WIDTH NO-BREAK SPACE */ continue; } /* fold into lowercase -- this will only fold characters in * the ASCII range, which is perfectly fine, because the * git folder name can only be composed of ascii characters */ return git__tolower(codepoint); } return 0; /* NULL byte -- end of string */ }
static int parse_section_header(git_config_parser *reader, char **section_out) { char *name, *name_end; int name_length, c, pos; int result; char *line; size_t line_len; git_parse_advance_ws(&reader->ctx); line = git__strndup(reader->ctx.line, reader->ctx.line_len); if (line == NULL) return -1; /* find the end of the variable's name */ name_end = strrchr(line, ']'); if (name_end == NULL) { git__free(line); set_parse_error(reader, 0, "Missing ']' in section header"); return -1; } GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1); name = git__malloc(line_len); GITERR_CHECK_ALLOC(name); name_length = 0; pos = 0; /* Make sure we were given a section header */ c = line[pos++]; assert(c == '['); c = line[pos++]; do { if (git__isspace(c)){ name[name_length] = '\0'; result = parse_section_header_ext(reader, line, name, section_out); git__free(line); git__free(name); return result; } if (!config_keychar(c) && c != '.') { set_parse_error(reader, pos, "Unexpected character in header"); goto fail_parse; } name[name_length++] = (char)git__tolower(c); } while ((c = line[pos++]) != ']'); if (line[pos - 1] != ']') { set_parse_error(reader, pos, "Unexpected end of file"); goto fail_parse; } git__free(line); name[name_length] = 0; *section_out = name; return 0; fail_parse: git__free(line); git__free(name); return -1; }