@@ -26,6 +26,13 @@ unsigned char sas7bdat_magic_number[32] = {
2626 0x09 , 0xc7 , 0x31 , 0x8c , 0x18 , 0x1f , 0x10 , 0x11
2727};
2828
29+ unsigned char sas7bdat_magic_number_alt [32 ] = {
30+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
31+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
32+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
33+ 0x00 , 0x00 , 0x00 , 0x00 , 0x18 , 0x1f , 0x10 , 0x11
34+ };
35+
2936unsigned char sas7bcat_magic_number [32 ] = {
3037 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
3138 0x00 , 0x00 , 0x00 , 0x00 , 0xc2 , 0xea , 0x81 , 0x63 ,
@@ -171,6 +178,7 @@ readstat_error_t sas_read_header(readstat_io_t *io, sas_header_info_t *hinfo,
171178 goto cleanup ;
172179 }
173180 if (memcmp (header_start .magic , sas7bdat_magic_number , sizeof (sas7bdat_magic_number )) != 0 &&
181+ memcmp (header_start .magic , sas7bdat_magic_number_alt , sizeof (sas7bdat_magic_number_alt )) != 0 &&
174182 memcmp (header_start .magic , sas7bcat_magic_number , sizeof (sas7bcat_magic_number )) != 0 ) {
175183 retval = READSTAT_ERROR_PARSE ;
176184 goto cleanup ;
@@ -309,9 +317,9 @@ readstat_error_t sas_read_header(readstat_io_t *io, sas_header_info_t *hinfo,
309317 retval = READSTAT_ERROR_READ ;
310318 goto cleanup ;
311319 }
312- char major , revision_tag ;
313- int minor , revision ;
314- if (sscanf (header_end .release , "%c.%04d%c%1d " , & major , & minor , & revision_tag , & revision ) != 4 ) {
320+ char major , revision_tag , revision ;
321+ int minor ;
322+ if (sscanf (header_end .release , "%c.%04d%c%c " , & major , & minor , & revision_tag , & revision ) != 4 ) {
315323 retval = READSTAT_ERROR_PARSE ;
316324 goto cleanup ;
317325 }
@@ -327,12 +335,21 @@ readstat_error_t sas_read_header(readstat_io_t *io, sas_header_info_t *hinfo,
327335 goto cleanup ;
328336 }
329337 // revision_tag is usually M, but J has been observed in the wild (not created with SAS?)
330- if (revision_tag != 'M' && revision_tag != 'J' ) {
338+ // files have also been observed with TK in place of the revision details.
339+ if (revision_tag != 'M' && revision_tag != 'J' && revision_tag != 'T' ) {
331340 retval = READSTAT_ERROR_PARSE ;
332341 goto cleanup ;
333342 }
334343 hinfo -> minor_version = minor ;
335- hinfo -> revision = revision ;
344+ if (revision >= '0' && revision <= '9' ) {
345+ hinfo -> revision = revision - '0' ;
346+ } else if (revision_tag == 'T' && revision == 'K' ) {
347+ // files have been observed with TK in place of the revision details.
348+ hinfo -> revision = 0 ;
349+ } else {
350+ retval = READSTAT_ERROR_PARSE ;
351+ goto cleanup ;
352+ }
336353
337354 if ((major == '8' || major == '9' ) && minor == 0 && revision == 0 ) {
338355 /* A bit of a hack, but most SAS installations are running a minor update */
0 commit comments