]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib: Add adouble_buf_parse()
authorVolker Lendecke <vl@samba.org>
Thu, 2 Oct 2025 08:38:24 +0000 (10:38 +0200)
committerVolker Lendecke <vl@samba.org>
Wed, 8 Oct 2025 08:01:30 +0000 (08:01 +0000)
Simplified version of ad_get that takes a buffer and does basic parsing of an
AppleDouble file format. The entries are represented as DATA_BLOBs directly
pointing at "buf" to avoid offset calculations in users of this.

Yes, this is a duplication of logic, but it makes the next patch
possible. Future patches could use this in ad_unpack()

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/lib/adouble.c
source3/lib/adouble.h

index d545460dab9c4b385cb370079e52bfb1c3a5acbc..0cea2ba23fe92554c4312407acb2cf697774638d 100644 (file)
@@ -2869,3 +2869,64 @@ AfpInfo *afpinfo_unpack(TALLOC_CTX *ctx, const void *data, bool validate)
 
        return ai;
 }
+
+bool adouble_buf_parse(const uint8_t *buf,
+                      size_t buflen,
+                      struct adouble_buf *ad)
+{
+       size_t i, nentries;
+
+       if (buflen < AD_HEADER_LEN) {
+               return false;
+       }
+
+       *ad = (struct adouble_buf){
+               .magic = PULL_BE_U32(buf, ADEDOFF_MAGIC),
+               .version = PULL_BE_U32(buf, ADEDOFF_VERSION),
+       };
+
+       if ((ad->magic != AD_MAGIC) || (ad->version != AD_VERSION)) {
+               return false;
+       }
+
+       nentries = PULL_BE_U16(buf, ADEDOFF_NENTRIES);
+
+       /*
+        * no overflow, nentries is just 16 bits
+        */
+
+       if ((AD_HEADER_LEN + (AD_ENTRY_LEN * (size_t)nentries)) > buflen) {
+               return false;
+       }
+
+       for (i = 0; i < nentries; i++) {
+               size_t eoff = AD_HEADER_LEN + i * AD_ENTRY_LEN;
+               uint32_t id = get_eid(PULL_BE_U32(buf, eoff));
+               uint32_t off = PULL_BE_U32(buf, eoff + 4);
+               uint32_t len = PULL_BE_U32(buf, eoff + 8);
+               bool ok;
+
+               if ((id == 0) || (id >= ADEID_MAX)) {
+                       return false;
+               }
+
+               ok = ad_entry_check_size(id, buflen, off, len);
+               if (!ok) {
+                       return false;
+               }
+
+               if (ad->entries[id].data != NULL) {
+                       /*
+                        * Duplicate id
+                        */
+                       return false;
+               }
+
+               ad->entries[i] = (DATA_BLOB){
+                       .data = discard_const_p(uint8_t, buf) + off,
+                       .length = len,
+               };
+       }
+
+       return true;
+}
index 3879b79fed17ba9a7ba8293d668c4ee8b76fbfd5..8fd4b7e69b6a3142bdf25076353c41af8c6066c9 100644 (file)
@@ -191,4 +191,14 @@ AfpInfo *afpinfo_new(TALLOC_CTX *ctx);
 ssize_t afpinfo_pack(const AfpInfo *ai, char *buf);
 AfpInfo *afpinfo_unpack(TALLOC_CTX *ctx, const void *data, bool validate);
 
+struct adouble_buf {
+       uint32_t magic;
+       uint32_t version;
+       DATA_BLOB entries[ADEID_MAX];
+};
+
+bool adouble_buf_parse(const uint8_t *buf,
+                      size_t buflen,
+                      struct adouble_buf *dst);
+
 #endif