Imported Upstream version 1.9.1
[platform/upstream/libzip.git] / lib / zip_buffer.c
index 3d79b09..a353ce0 100644 (file)
@@ -1,10 +1,10 @@
 /*
  zip_buffer.c -- bounds checked access to memory buffer
- Copyright (C) 2014 Dieter Baron and Thomas Klausner
+ Copyright (C) 2014-2021 Dieter Baron and Thomas Klausner
+
  This file is part of libzip, a library to manipulate ZIP archives.
- The authors can be contacted at <libzip@nih.at>
+ The authors can be contacted at <info@libzip.org>
+
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
@@ -17,7 +17,7 @@
  3. The names of the authors may not be used to endorse or promote
  products derived from this software without specific prior
  written permission.
+
  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 #include "zipint.h"
 
 zip_uint8_t *
-_zip_buffer_data(zip_buffer_t *buffer)
-{
+_zip_buffer_data(zip_buffer_t *buffer) {
     return buffer->data;
 }
 
 
 void
-_zip_buffer_free(zip_buffer_t *buffer)
-{
+_zip_buffer_free(zip_buffer_t *buffer) {
     if (buffer == NULL) {
         return;
     }
-    
+
     if (buffer->free_data) {
         free(buffer->data);
     }
-    
+
     free(buffer);
 }
 
 
 bool
-_zip_buffer_eof(zip_buffer_t *buffer)
-{
+_zip_buffer_eof(zip_buffer_t *buffer) {
     return buffer->ok && buffer->offset == buffer->size;
 }
 
 
 zip_uint8_t *
-_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length)
-{
+_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length) {
     zip_uint8_t *data;
-    
-    if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
-        buffer->ok = false;
-        return NULL;
+
+    data = _zip_buffer_peek(buffer, length);
+
+    if (data != NULL) {
+        buffer->offset += length;
     }
-    
-    data = buffer->data + buffer->offset;
-    buffer->offset += length;
+
     return data;
 }
 
 
 zip_uint16_t
-_zip_buffer_get_16(zip_buffer_t *buffer)
-{
+_zip_buffer_get_16(zip_buffer_t *buffer) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 2);
-    
+
     if (data == NULL) {
         return 0;
     }
-    
+
     return (zip_uint16_t)(data[0] + (data[1] << 8));
 }
 
 
 zip_uint32_t
-_zip_buffer_get_32(zip_buffer_t *buffer)
-{
+_zip_buffer_get_32(zip_buffer_t *buffer) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 4);
-    
+
     if (data == NULL) {
         return 0;
     }
-    
+
     return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0];
 }
 
 
 zip_uint64_t
-_zip_buffer_get_64(zip_buffer_t *buffer)
-{
+_zip_buffer_get_64(zip_buffer_t *buffer) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 8);
-    
+
     if (data == NULL) {
         return 0;
     }
@@ -120,33 +112,41 @@ _zip_buffer_get_64(zip_buffer_t *buffer)
 }
 
 
-
 zip_uint8_t
-_zip_buffer_get_8(zip_buffer_t *buffer)
-{
+_zip_buffer_get_8(zip_buffer_t *buffer) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 1);
-    
+
     if (data == NULL) {
         return 0;
     }
-    
+
     return data[0];
 }
 
 
 zip_uint64_t
-_zip_buffer_left(zip_buffer_t *buffer)
-{
+_zip_buffer_left(zip_buffer_t *buffer) {
     return buffer->ok ? buffer->size - buffer->offset : 0;
 }
 
 
+zip_uint64_t
+_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) {
+    if (_zip_buffer_left(buffer) < length) {
+        length = _zip_buffer_left(buffer);
+    }
+
+    memcpy(data, _zip_buffer_get(buffer, length), length);
+
+    return length;
+}
+
+
 zip_buffer_t *
-_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size)
-{
+_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) {
     bool free_data = (data == NULL);
     zip_buffer_t *buffer;
-    
+
     if (data == NULL) {
         if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
             return NULL;
@@ -159,107 +159,113 @@ _zip_buffer_new(zip_uint8_t *data, zip_uint64_t size)
         }
         return NULL;
     }
-    
+
     buffer->ok = true;
     buffer->data = data;
     buffer->size = size;
     buffer->offset = 0;
     buffer->free_data = free_data;
-    
+
     return buffer;
 }
 
 
 zip_buffer_t *
-_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error)
-{
+_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error) {
     zip_buffer_t *buffer;
-    
+
     if ((buffer = _zip_buffer_new(buf, size)) == NULL) {
         zip_error_set(error, ZIP_ER_MEMORY, 0);
         return NULL;
     }
-    
+
     if (_zip_read(src, buffer->data, size, error) < 0) {
         _zip_buffer_free(buffer);
         return NULL;
     }
-    
+
     return buffer;
 }
 
 
 zip_uint64_t
-_zip_buffer_offset(zip_buffer_t *buffer)
-{
+_zip_buffer_offset(zip_buffer_t *buffer) {
     return buffer->ok ? buffer->offset : 0;
 }
 
 
 bool
-_zip_buffer_ok(zip_buffer_t *buffer)
-{
+_zip_buffer_ok(zip_buffer_t *buffer) {
     return buffer->ok;
 }
 
 
+zip_uint8_t *
+_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) {
+    zip_uint8_t *data;
+
+    if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
+        buffer->ok = false;
+        return NULL;
+    }
+
+    data = buffer->data + buffer->offset;
+    return data;
+}
+
 int
-_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length)
-{
+_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) {
     zip_uint8_t *dst = _zip_buffer_get(buffer, length);
-    
+
     if (dst == NULL) {
         return -1;
     }
-    
+
     memcpy(dst, src, length);
     return 0;
 }
 
 
 int
-_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i)
-{
+_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 2);
-    
+
     if (data == NULL) {
         return -1;
     }
 
     data[0] = (zip_uint8_t)(i & 0xff);
     data[1] = (zip_uint8_t)((i >> 8) & 0xff);
-    
+
     return 0;
 }
 
 
 int
-_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i)
-{
+_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 4);
-    
+
     if (data == NULL) {
         return -1;
     }
-    
+
     data[0] = (zip_uint8_t)(i & 0xff);
     data[1] = (zip_uint8_t)((i >> 8) & 0xff);
     data[2] = (zip_uint8_t)((i >> 16) & 0xff);
     data[3] = (zip_uint8_t)((i >> 24) & 0xff);
-    
+
     return 0;
 }
 
 
 int
-_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i)
-{
+_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 8);
-    
+
     if (data == NULL) {
         return -1;
     }
-    
+
     data[0] = (zip_uint8_t)(i & 0xff);
     data[1] = (zip_uint8_t)((i >> 8) & 0xff);
     data[2] = (zip_uint8_t)((i >> 16) & 0xff);
@@ -268,43 +274,51 @@ _zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i)
     data[5] = (zip_uint8_t)((i >> 40) & 0xff);
     data[6] = (zip_uint8_t)((i >> 48) & 0xff);
     data[7] = (zip_uint8_t)((i >> 56) & 0xff);
-    
+
     return 0;
 }
 
 
 int
-_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i)
-{
+_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) {
     zip_uint8_t *data = _zip_buffer_get(buffer, 1);
-    
+
     if (data == NULL) {
         return -1;
     }
-    
+
     data[0] = i;
-    
+
     return 0;
 }
 
 
 int
-_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset)
-{
+_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
     if (offset > buffer->size) {
         buffer->ok = false;
         return -1;
     }
-    
+
     buffer->ok = true;
     buffer->offset = offset;
-    
+
     return 0;
 }
 
 
+int
+_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) {
+    zip_uint64_t offset = buffer->offset + length;
+
+    if (offset < buffer->offset) {
+        buffer->ok = false;
+        return -1;
+    }
+    return _zip_buffer_set_offset(buffer, offset);
+}
+
 zip_uint64_t
-_zip_buffer_size(zip_buffer_t *buffer)
-{
+_zip_buffer_size(zip_buffer_t *buffer) {
     return buffer->size;
 }