Code

Do a better job at guessing unknown character sets
[git.git] / refs.c
diff --git a/refs.c b/refs.c
index 2ae3235b2f0a7a2860eb8e51a999db68490a1c78..2694e7066d2dfdb155016ac3cd0104913b475c79 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -150,7 +150,7 @@ static struct ref_list *sort_ref_list(struct ref_list *list)
  * Future: need to be in "struct repository"
  * when doing a full libification.
  */
-struct cached_refs {
+static struct cached_refs {
        char did_loose;
        char did_packed;
        struct ref_list *loose;
@@ -603,15 +603,20 @@ int get_ref_sha1(const char *ref, unsigned char *sha1)
 
 static inline int bad_ref_char(int ch)
 {
-       return (((unsigned) ch) <= ' ' ||
-               ch == '~' || ch == '^' || ch == ':' ||
-               /* 2.13 Pattern Matching Notation */
-               ch == '?' || ch == '*' || ch == '[');
+       if (((unsigned) ch) <= ' ' ||
+           ch == '~' || ch == '^' || ch == ':')
+               return 1;
+       /* 2.13 Pattern Matching Notation */
+       if (ch == '?' || ch == '[') /* Unsupported */
+               return 1;
+       if (ch == '*') /* Supported at the end */
+               return 2;
+       return 0;
 }
 
 int check_ref_format(const char *ref)
 {
-       int ch, level;
+       int ch, level, bad_type;
        const char *cp = ref;
 
        level = 0;
@@ -622,13 +627,19 @@ int check_ref_format(const char *ref)
                        return -1; /* should not end with slashes */
 
                /* we are at the beginning of the path component */
-               if (ch == '.' || bad_ref_char(ch))
+               if (ch == '.')
                        return -1;
+               bad_type = bad_ref_char(ch);
+               if (bad_type) {
+                       return (bad_type == 2 && !*cp) ? -3 : -1;
+               }
 
                /* scan the rest of the path component */
                while ((ch = *cp++) != 0) {
-                       if (bad_ref_char(ch))
-                               return -1;
+                       bad_type = bad_ref_char(ch);
+                       if (bad_type) {
+                               return (bad_type == 2 && !*cp) ? -3 : -1;
+                       }
                        if (ch == '/')
                                break;
                        if (ch == '.' && *cp == '.')
@@ -1095,8 +1106,7 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
                len += sprintf(logrec + len - 1, "\t%.*s\n", msglen, msg) - 1;
        written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
        free(logrec);
-       close(logfd);
-       if (written != len)
+       if (close(logfd) != 0 || written != len)
                return error("Unable to append to %s", log_file);
        return 0;
 }
@@ -1193,8 +1203,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
                goto error_free_return;
        }
        written = write_in_full(fd, ref, len);
-       close(fd);
-       if (written != len) {
+       if (close(fd) != 0 || written != len) {
                error("Unable to write to %s", lockpath);
                goto error_unlink_return;
        }
@@ -1291,7 +1300,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
                                if (hashcmp(logged_sha1, sha1)) {
                                        fprintf(stderr,
                                                "warning: Log %s has gap after %s.\n",
-                                               logfile, show_rfc2822_date(date, tz));
+                                               logfile, show_date(date, tz, DATE_RFC2822));
                                }
                        }
                        else if (date == at_time) {
@@ -1304,7 +1313,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
                                if (hashcmp(logged_sha1, sha1)) {
                                        fprintf(stderr,
                                                "warning: Log %s unexpectedly ended on %s.\n",
-                                               logfile, show_rfc2822_date(date, tz));
+                                               logfile, show_date(date, tz, DATE_RFC2822));
                                }
                        }
                        munmap(log_mapped, mapsz);