From 3a761d723e674318a7ba578b0cec0f6afe5996df Mon Sep 17 00:00:00 2001 From: semvis123 Date: Tue, 8 Aug 2023 22:31:04 +0200 Subject: [PATCH] Add support for annotation authors --- catdoc.go | 8 ++++++ catdoc.wasm | Bin 89776 -> 90438 bytes catdoc/src/Makefile | 2 +- catdoc/src/analyze.c | 65 +++++++++++++++++++++++++++++++++++++++++++ catdoc/src/catdoc.c | 10 ++++++- catdoc/src/catdoc.h | 4 ++- catdoc_test.go | 20 +++++++++++++ test.doc | Bin 22528 -> 23552 bytes 8 files changed, 106 insertions(+), 3 deletions(-) diff --git a/catdoc.go b/catdoc.go index 59b16c5..000cea3 100644 --- a/catdoc.go +++ b/catdoc.go @@ -102,6 +102,14 @@ func GetCommentsFromFile(file io.ReadSeeker) (string, error) { return callWASMFuncWithFile("get_comments", file) } +func GetAnnotationAuthorsFromFile(file io.ReadSeeker) ([]string, error) { + r, err := callWASMFuncWithFile("get_annotation_authors", file) + if err != nil { + return nil, err + } + return strings.Split(r, "\n"), nil +} + func GetVersion() (string, error) { return callWASMFunc("get_version", nil) } diff --git a/catdoc.wasm b/catdoc.wasm index 27f960d47de1fef6c79b186a5a1d3fd8c2c7cac8..b9faf816900d5d19f8a1bf2d3e3dba6202cb881c 100755 GIT binary patch delta 22326 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 delta 21483 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 Qp%FWwc;gwXztR1_0W3ls6aWAK diff --git a/catdoc/src/Makefile b/catdoc/src/Makefile index 52d6688..d2655f7 100644 --- a/catdoc/src/Makefile +++ b/catdoc/src/Makefile @@ -105,7 +105,7 @@ catdoc-wasm: emsdk.uptodate -I. -O3 -DHAVE_CONFIG_H \ -DCATDOC_VERSION=\"0.95\" \ -DCHARSETPATH=\"charsets\" \ - -sEXPORTED_FUNCTIONS=_get_text,_get_author,_get_last_author,_get_version,_get_title,_get_subject,_get_keywords,_get_comments\ + -sEXPORTED_FUNCTIONS=_get_text,_get_author,_get_last_author,_get_version,_get_title,_get_subject,_get_keywords,_get_comments,_get_annotation_authors\ -sSTANDALONE_WASM -sWARN_ON_UNDEFINED_SYMBOLS=0 \ --no-entry -sFILESYSTEM=1 -sALLOW_MEMORY_GROWTH -sMAXIMUM_MEMORY=1GB diff --git a/catdoc/src/analyze.c b/catdoc/src/analyze.c index 1ecdd9d..fa25c92 100644 --- a/catdoc/src/analyze.c +++ b/catdoc/src/analyze.c @@ -18,6 +18,9 @@ extern char ole_sign[], zip_sign[]; /* from ole.c */ char rtf_sign[] = "{\\rtf"; char old_word_sign[] = {0xdb, 0xa5, 0}; char write_sign[] = {0x31, 0xBE, 0}; +unsigned char sttbfRMark[] = {0x00, 0x00, 0x07, 0x00, 0x55, 0x00, + 0x6E, 0x00, 0x6B, 0x00, 0x6E, 0x00, + 0x6F, 0x00, 0x77, 0x00, 0x6E, 0x00}; int verbose = 0; unsigned char *read_metadata(unsigned char *buffer, metadata metadata_type) { @@ -38,6 +41,64 @@ unsigned char *read_metadata(unsigned char *buffer, metadata metadata_type) { return NULL; } +int find_offset(FILE *f, unsigned char *mark, int mark_length) { + int offset = 0; + int block_size = 1024 * 25; + int pos = 0; + int bpos = 0; + unsigned char buf[block_size]; + int block_n = 0; + + while (!feof(f)) { + long n = fread(buf, 1, block_size, f); + while (bpos != n) { + if (buf[bpos] == mark[pos]) { + pos++; + bpos++; + if (pos == mark_length) { + offset = block_n * block_size + bpos - pos; + return offset; + } + } else { + bpos -= pos; + bpos++; + pos = 0; + } + } + bpos = 0; + block_n++; + } + fprintf(stderr, "stttbfRMark offset is not found"); + exit(1); +} + +void read_annotation_authors(FILE *f) { + int offset = find_offset(f, sttbfRMark, 18) - 4; + fseek(f, offset, SEEK_SET); + + int block_size = 1024; + unsigned char buf[2]; + fread(buf, 1, 2, f); + if (buf[0] != 0xff || buf[1] != 0xff) { + fprintf(stderr, "stttbfRMark offset is invalid"); + exit(1); + } + fread(buf, 1, 2, f); + unsigned int count = getshort(buf, 0) - 1; + fseek(f, 18, SEEK_CUR); + for (int i = 0; i < count; i++) { + fread(buf, 1, 2, f); + unsigned int str_len = getshort(buf, 0); + unsigned short *str = calloc(str_len, 2); + fread(str, 2, str_len, f); + for (int j = 0; j < str_len; j++) { + printf("%lc", str[j]); + } + printf("\n"); + free(str); + } +} + /********************************************************************* * Determines format of input file and calls parse_word_header or * process_file if @@ -45,6 +106,10 @@ unsigned char *read_metadata(unsigned char *buffer, metadata metadata_type) { * return not 0 when error ********************************************************************/ int analyze_format(FILE *f, metadata metadata_type) { + if (metadata_type == annotation_authors) { + read_annotation_authors(f); + return 0; + } unsigned char buffer[129]; long offset = 0; FILE *new_file, *ole_file; diff --git a/catdoc/src/catdoc.c b/catdoc/src/catdoc.c index 3d83926..3709d44 100644 --- a/catdoc/src/catdoc.c +++ b/catdoc/src/catdoc.c @@ -56,7 +56,7 @@ int main(int argc, char **argv) { get_locale_charset(); #endif metadata metadata_type = none; - while ((c = getopt(argc, argv, "Vls:d:f:taubxv8wALTSKCm:")) != -1) { + while ((c = getopt(argc, argv, "Vls:d:f:taubxv8wALTSKCUm:")) != -1) { switch (c) { case 's': check_charset(&source_csname, optarg); @@ -104,6 +104,9 @@ int main(int argc, char **argv) { case 'C': metadata_type = comments; break; + case 'U': + metadata_type = annotation_authors; + break; case 'm': { char *endptr; wrap_margin = (int)strtol(optarg, &endptr, 0); @@ -246,3 +249,8 @@ void get_comments() { char *args[] = {"", "-C", "/input_file/file.doc"}; main(3, args); } + +void get_annotation_authors() { + char *args[] = {"", "-U", "/input_file/file.doc"}; + main(3, args); +} diff --git a/catdoc/src/catdoc.h b/catdoc/src/catdoc.h index 0a8f932..826b82d 100644 --- a/catdoc/src/catdoc.h +++ b/catdoc/src/catdoc.h @@ -227,6 +227,7 @@ void get_title(); void get_subject(); void get_keywords(); void get_comments(); +void get_annotation_authors(); char *find_file(char *name, const char *path); char *stradd(const char *s1, const char *s2); @@ -255,7 +256,8 @@ typedef enum { title, subject, keywords, - comments + comments, + annotation_authors } metadata; int analyze_format(FILE *f, metadata metadata_type); void list_charsets(void); diff --git a/catdoc_test.go b/catdoc_test.go index 5c8ff69..7e3e14c 100644 --- a/catdoc_test.go +++ b/catdoc_test.go @@ -31,6 +31,22 @@ func testFileFunc(title, expected string, fun func(io.ReadSeeker) (string, error } } +func testFileFuncArr(title string, expected []string, fun func(io.ReadSeeker) ([]string, error), t *testing.T) { + f, err := os.Open("test.doc") + if err != nil { + t.Fatalf("could not open test document, %v", err) + } + arr, err := fun(f) + if err != nil { + t.Fatalf("expected error to be nil, got %v", err) + } + for i := range expected { + if arr[i] != expected[i] { + t.Fatalf("expected %s to be \"%v\", got %v", title, expected, arr) + } + } +} + func TestGetTextFromFile(t *testing.T) { testFileFunc("text", "text-inside-doc", gocatdoc.GetTextFromFile, t) } @@ -58,3 +74,7 @@ func TestGetKeywordsFromFile(t *testing.T) { func TestGetCommentsFromFile(t *testing.T) { testFileFunc("comments", "Comments", gocatdoc.GetCommentsFromFile, t) } + +func TestGetAnnotationAuthorsFromFile(t *testing.T) { + testFileFuncArr("annoation_authors", []string{"H. Potter"}, gocatdoc.GetAnnotationAuthorsFromFile, t) +} diff --git a/test.doc b/test.doc index 918bea8a7ebad978b6541e0375ce8f7ee62c30ff..16c96d77a13e3bdf897c25863b0883e466038cc0 100644 GIT binary patch delta 2358 zcmbUiT})eL^nCrHz{<~ zd(OFC{)8>Bu@yIKx!V_1rQg+o0z}&lx%0o#r*bOFGmAh6Z{F@Oszu3CVM*kFZu`CsnGIq-u}PP2GlRB2KW>WH)@UmTth}3W@L~jRL4qr?K5;Wrk|7< z8SVvc&MCL&I{fZHyB1{L%4c3kNv{&XvD*`FSm>Bu!Cts!khe6>7Os9!yjPjx%faG{ zX&#;nd1r55AN<_;^(OWz2b>?vrMH_tm;Z=-nvmzPJU3G6Gy(VTs?FVB$=m1e>U^!KcwKGK7vsPpRv=a)?(A%D?_`dae#K54W5us& zMi^)#?+>k=Ge#=3pFxo^GOb$&?P|G7!zwfCstH}Q2Ubm6*=_JZxfb9D`wP%sq=QKi zaQLH;LKHAF6;#M$)wP+ar*D@ri~Q?p+ffbVJ`WWru0qtvU5)i=+GPzQCIdeq5|kpo zE>*(ymS^Bm=QsprFDrqndPTT%b_pJq+yP3Dayt^c4`%)EiX9HQ;+ZZqX4wH)W z2^jwPSz%c5sUkZ9qH8K718AG2kAV)RAptKUitrL7*dEm^WE`zyY_)BQF_%1TYf^tGe=jfF3@5&5`Ir_=t;7HzO5TZnt2;&(&^pPIM6mwRC>2G@x<3-PrhT_?lTMVnCY63Ohv^+pSh#0-E2xp!9+M1 z6B9z8IU$pkcyd2 zisHp!9FhXAbtUY#DhrMgq>2x@HUd>n68%|Myp2G?Z z&7=SLv+)=vg#J^Zh!77>3UjIbSBgEKjFOw-!`$q9r#7suz!%;371NKSV_Cg4!2SZf C4d1u` delta 1460 zcmbVL-%C?*6hGg4uioX<>1u0Q2&J{TMl+4bN?949Nwty75fMs|fsz?f8Nu#DZ&7Jq zD)FTr>mkTph#4r0da0+Vr~UwgsE2xs7}+`ByJNQXi_ZA&^F2R4-}|}uoUfG?)*~^o zOEk}P3~K2<6O<8tT;=TlgoP4SxQM1UK8FXtz)DP2Vw{lkb$)fHe6F))t@_+&y`S;6lfAlIM%n=&FUH>NW(pKI8EgFO5S zkSg$tk?Lvy+Ln64#NvaeiUg#5^0Tom%;lwNR^lL*54sMfQ$?q6XKN;|cb|Om7JKCw z$3u?1CHb7cf^nLV_lPZs)M+w4f41K7w-@*YU&jK{v4`_c)sKlJeguO7L^4K-FZZ!) zlg7sNoGwQ0*1Re!>n0UQXlySoWS{l3UxIRtdAF5Smt;%Sv0Cg==epmO(^Wi<_a$TZ zy5@AZ$Av0!<@0&FwqilJ%KfL3<{apmYRwQHTlXeRd#dhUl?clAV6=8EI9J-hhk0?e z$?;%gx(s&|!GmA{7nzRhYIrAn*m?-OJ4S&{b&ot%IUGL4CWqR;7}G5Q9^BC)8^Ry& z88xDj5nj{~Vn|&SumMn25>CS~u2Hyv{}d)QZ0OsUL$^eH%w+}O({sF^57gk@_GX7p zbYz26s43ADrbh}T%>aFZB0onJ6{BN@Js936M60~N>5lA*1Z00CWjs7KZQ6F^fRJZg zR%UY_<&)8n{<>#aT2Y_*(!ZPLUViCpu%ATVHLUoCqp#LXqF>yMk5msFzM-y07@uK* zycF-L5_CQ2Llfd$HI>u*&DP7W@%@#ghvHh`MxuY=>nEMW?=+Sck