@@ -1812,9 +1812,114 @@ static int packed_fsck_ref_header(struct fsck_options *o,
1812
1812
return 0 ;
1813
1813
}
1814
1814
1815
+ static int packed_fsck_ref_peeled_line (struct fsck_options * o ,
1816
+ struct ref_store * ref_store ,
1817
+ unsigned long line_number ,
1818
+ const char * start , const char * eol )
1819
+ {
1820
+ struct strbuf packed_entry = STRBUF_INIT ;
1821
+ struct fsck_ref_report report = { 0 };
1822
+ struct object_id peeled ;
1823
+ const char * p ;
1824
+ int ret = 0 ;
1825
+
1826
+ /*
1827
+ * Skip the '^' and parse the peeled oid.
1828
+ */
1829
+ start ++ ;
1830
+ if (parse_oid_hex_algop (start , & peeled , & p , ref_store -> repo -> hash_algo )) {
1831
+ strbuf_addf (& packed_entry , "packed-refs line %lu" , line_number );
1832
+ report .path = packed_entry .buf ;
1833
+
1834
+ ret = fsck_report_ref (o , & report ,
1835
+ FSCK_MSG_BAD_PACKED_REF_ENTRY ,
1836
+ "'%.*s' has invalid peeled oid" ,
1837
+ (int )(eol - start ), start );
1838
+ goto cleanup ;
1839
+ }
1840
+
1841
+ if (p != eol ) {
1842
+ strbuf_addf (& packed_entry , "packed-refs line %lu" , line_number );
1843
+ report .path = packed_entry .buf ;
1844
+
1845
+ ret = fsck_report_ref (o , & report ,
1846
+ FSCK_MSG_BAD_PACKED_REF_ENTRY ,
1847
+ "has trailing garbage after peeled oid '%.*s'" ,
1848
+ (int )(eol - p ), p );
1849
+ goto cleanup ;
1850
+ }
1851
+
1852
+ cleanup :
1853
+ strbuf_release (& packed_entry );
1854
+ return ret ;
1855
+ }
1856
+
1857
+ static int packed_fsck_ref_main_line (struct fsck_options * o ,
1858
+ struct ref_store * ref_store ,
1859
+ unsigned long line_number ,
1860
+ struct strbuf * refname ,
1861
+ const char * start , const char * eol )
1862
+ {
1863
+ struct strbuf packed_entry = STRBUF_INIT ;
1864
+ struct fsck_ref_report report = { 0 };
1865
+ struct object_id oid ;
1866
+ const char * p ;
1867
+ int ret = 0 ;
1868
+
1869
+ if (parse_oid_hex_algop (start , & oid , & p , ref_store -> repo -> hash_algo )) {
1870
+ strbuf_addf (& packed_entry , "packed-refs line %lu" , line_number );
1871
+ report .path = packed_entry .buf ;
1872
+
1873
+ ret = fsck_report_ref (o , & report ,
1874
+ FSCK_MSG_BAD_PACKED_REF_ENTRY ,
1875
+ "'%.*s' has invalid oid" ,
1876
+ (int )(eol - start ), start );
1877
+ goto cleanup ;
1878
+ }
1879
+
1880
+ if (p == eol || !isspace (* p )) {
1881
+ strbuf_addf (& packed_entry , "packed-refs line %lu" , line_number );
1882
+ report .path = packed_entry .buf ;
1883
+
1884
+ ret = fsck_report_ref (o , & report ,
1885
+ FSCK_MSG_BAD_PACKED_REF_ENTRY ,
1886
+ "has no space after oid '%s' but with '%.*s'" ,
1887
+ oid_to_hex (& oid ), (int )(eol - p ), p );
1888
+ goto cleanup ;
1889
+ }
1890
+
1891
+ p ++ ;
1892
+ strbuf_reset (refname );
1893
+ strbuf_add (refname , p , eol - p );
1894
+ if (refname_contains_nul (refname )) {
1895
+ strbuf_addf (& packed_entry , "packed-refs line %lu" , line_number );
1896
+ report .path = packed_entry .buf ;
1897
+
1898
+ ret = fsck_report_ref (o , & report ,
1899
+ FSCK_MSG_BAD_PACKED_REF_ENTRY ,
1900
+ "refname '%s' contains NULL binaries" ,
1901
+ refname -> buf );
1902
+ }
1903
+
1904
+ if (check_refname_format (refname -> buf , 0 )) {
1905
+ strbuf_addf (& packed_entry , "packed-refs line %lu" , line_number );
1906
+ report .path = packed_entry .buf ;
1907
+
1908
+ ret = fsck_report_ref (o , & report ,
1909
+ FSCK_MSG_BAD_REF_NAME ,
1910
+ "has bad refname '%s'" , refname -> buf );
1911
+ }
1912
+
1913
+ cleanup :
1914
+ strbuf_release (& packed_entry );
1915
+ return ret ;
1916
+ }
1917
+
1815
1918
static int packed_fsck_ref_content (struct fsck_options * o ,
1919
+ struct ref_store * ref_store ,
1816
1920
const char * start , const char * eof )
1817
1921
{
1922
+ struct strbuf refname = STRBUF_INIT ;
1818
1923
unsigned long line_number = 1 ;
1819
1924
const char * eol ;
1820
1925
int ret = 0 ;
@@ -1827,6 +1932,21 @@ static int packed_fsck_ref_content(struct fsck_options *o,
1827
1932
line_number ++ ;
1828
1933
}
1829
1934
1935
+ while (start < eof ) {
1936
+ ret |= packed_fsck_ref_next_line (o , line_number , start , eof , & eol );
1937
+ ret |= packed_fsck_ref_main_line (o , ref_store , line_number , & refname , start , eol );
1938
+ start = eol + 1 ;
1939
+ line_number ++ ;
1940
+ if (start < eof && * start == '^' ) {
1941
+ ret |= packed_fsck_ref_next_line (o , line_number , start , eof , & eol );
1942
+ ret |= packed_fsck_ref_peeled_line (o , ref_store , line_number ,
1943
+ start , eol );
1944
+ start = eol + 1 ;
1945
+ line_number ++ ;
1946
+ }
1947
+ }
1948
+
1949
+ strbuf_release (& refname );
1830
1950
return ret ;
1831
1951
}
1832
1952
@@ -1884,7 +2004,7 @@ static int packed_fsck(struct ref_store *ref_store,
1884
2004
goto cleanup ;
1885
2005
}
1886
2006
1887
- ret = packed_fsck_ref_content (o , packed_ref_content .buf ,
2007
+ ret = packed_fsck_ref_content (o , ref_store , packed_ref_content .buf ,
1888
2008
packed_ref_content .buf + packed_ref_content .len );
1889
2009
1890
2010
cleanup :
0 commit comments