LCOV - code coverage report
Current view: top level - glib - gstdio-private.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 100.0 % 81 81
Test Date: 2026-08-11 05:12:37 Functions: 100.0 % 2 2
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* gstdio-private.c - private glib functions for gstdio.c
       2                 :             :  *
       3                 :             :  * Copyright 2004 Tor Lillqvist
       4                 :             :  * Copyright 2018 Руслан Ижбулатов
       5                 :             :  *
       6                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       7                 :             :  *
       8                 :             :  * This library is free software; you can redistribute it and/or
       9                 :             :  * modify it under the terms of the GNU Lesser General Public
      10                 :             :  * License as published by the Free Software Foundation; either
      11                 :             :  * version 2.1 of the License, or (at your option) any later version.
      12                 :             :  *
      13                 :             :  * This library is distributed in the hope that it will be useful,
      14                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16                 :             :  * Lesser General Public License for more details.
      17                 :             :  *
      18                 :             :  * You should have received a copy of the GNU Lesser General Public License
      19                 :             :  * along with this library; if not, see <http://www.gnu.org/licenses/>.
      20                 :             :  */
      21                 :             : 
      22                 :             : /* Strips "\\\\?\\" extended prefix or
      23                 :             :  * "\\??\\" NT Object Manager prefix from
      24                 :             :  * @str in-place, using memmove.
      25                 :             :  * @str_size must point to the size of @str
      26                 :             :  * in gunichar2s, including NUL-terminator
      27                 :             :  * (if @str is NUL-terminated; it doesn't have to be).
      28                 :             :  * On return @str_size will correctly reflect changes
      29                 :             :  * in @str size (if any).
      30                 :             :  * Returns TRUE if @str was modified.
      31                 :             :  */
      32                 :             : static gboolean
      33                 :          38 : _g_win32_strip_extended_ntobjm_prefix (gunichar2 *str,
      34                 :             :                                        gsize     *str_size)
      35                 :             : {
      36                 :          38 :   const wchar_t *extended_prefix = L"\\\\?\\";
      37                 :          38 :   const gsize    extended_prefix_len = wcslen (extended_prefix);
      38                 :          38 :   const gsize    extended_prefix_len_bytes = sizeof (gunichar2) * extended_prefix_len;
      39                 :          38 :   const gsize    extended_prefix_with_drive_len_bytes = sizeof (gunichar2) * (extended_prefix_len + 2);
      40                 :          38 :   const wchar_t *ntobjm_prefix = L"\\??\\";
      41                 :          38 :   const gsize    ntobjm_prefix_len = wcslen (ntobjm_prefix);
      42                 :          38 :   const gsize    ntobjm_prefix_len_bytes = sizeof (gunichar2) * ntobjm_prefix_len;
      43                 :          38 :   const gsize    ntobjm_prefix_with_drive_len_bytes = sizeof (gunichar2) * (ntobjm_prefix_len + 2);
      44                 :          38 :   gboolean do_move = FALSE;
      45                 :          38 :   gsize move_shift = 0;
      46                 :             : 
      47                 :          38 :   if ((*str_size) * sizeof (gunichar2) > extended_prefix_with_drive_len_bytes &&
      48                 :          54 :       memcmp (str,
      49                 :          27 :               extended_prefix,
      50                 :          54 :               extended_prefix_len_bytes) == 0 &&
      51                 :          15 :       iswascii (str[extended_prefix_len]) &&
      52                 :          13 :       iswalpha (str[extended_prefix_len]) &&
      53                 :          13 :       str[extended_prefix_len + 1] == L':')
      54                 :             :    {
      55                 :          10 :      do_move = TRUE;
      56                 :          10 :      move_shift = extended_prefix_len;
      57                 :          10 :    }
      58                 :          28 :   else if ((*str_size) * sizeof (gunichar2) > ntobjm_prefix_with_drive_len_bytes &&
      59                 :          34 :            memcmp (str,
      60                 :          17 :                    ntobjm_prefix,
      61                 :          34 :                    ntobjm_prefix_len_bytes) == 0 &&
      62                 :          11 :            iswascii (str[ntobjm_prefix_len]) &&
      63                 :           9 :            iswalpha (str[ntobjm_prefix_len]) &&
      64                 :           9 :            str[ntobjm_prefix_len + 1] == L':')
      65                 :             :     {
      66                 :           6 :       do_move = TRUE;
      67                 :           6 :       move_shift = ntobjm_prefix_len;
      68                 :           6 :     }
      69                 :             : 
      70                 :          38 :   if (do_move)
      71                 :             :     {
      72                 :          16 :       *str_size -= move_shift;
      73                 :          48 :       memmove (str,
      74                 :          16 :                str + move_shift,
      75                 :          16 :                (*str_size) * sizeof (gunichar2));
      76                 :          16 :     }
      77                 :             : 
      78                 :          38 :   return do_move;
      79                 :             : }
      80                 :             : 
      81                 :             : static int
      82                 :         156 : _g_win32_copy_and_maybe_terminate (const guchar *data,
      83                 :             :                                    gsize         in_to_copy,
      84                 :             :                                    gunichar2    *buf,
      85                 :             :                                    gsize         buf_size,
      86                 :             :                                    gunichar2   **alloc_buf,
      87                 :             :                                    gboolean      terminate)
      88                 :             : {
      89                 :         156 :   gsize to_copy = in_to_copy;
      90                 :             :   /* Number of bytes we can use to add extra zeroes for NUL-termination.
      91                 :             :    * 0 means that we can destroy up to 2 bytes of data,
      92                 :             :    * 1 means that we can destroy up to 1 byte of data,
      93                 :             :    * 2 means that we do not perform destructive NUL-termination
      94                 :             :    */
      95                 :         156 :   gsize extra_bytes = terminate ? 2 : 0;
      96                 :             :   char *buf_in_chars;
      97                 :             : 
      98                 :         156 :   if (to_copy == 0)
      99                 :           8 :     return 0;
     100                 :             : 
     101                 :             :   /* 2 bytes is sizeof (wchar_t), for an extra NUL-terminator. */
     102                 :         148 :   if (buf)
     103                 :             :     {
     104                 :         124 :       if (to_copy >= buf_size)
     105                 :             :         {
     106                 :          74 :           extra_bytes = 0;
     107                 :          74 :           to_copy = buf_size;
     108                 :          74 :         }
     109                 :          50 :       else if (to_copy > buf_size - 2)
     110                 :             :         {
     111                 :          18 :           extra_bytes = 1;
     112                 :          18 :         }
     113                 :             : 
     114                 :         124 :       memcpy (buf, data, to_copy);
     115                 :         124 :     }
     116                 :             :   else
     117                 :             :     {
     118                 :             :       /* Note that SubstituteNameLength is USHORT, so to_copy + 2, being
     119                 :             :        * gsize, never overflows.
     120                 :             :        */
     121                 :          24 :       *alloc_buf = g_malloc (to_copy + extra_bytes);
     122                 :          24 :       memcpy (*alloc_buf, data, to_copy);
     123                 :             :     }
     124                 :             : 
     125                 :         148 :   if (!terminate)
     126                 :          71 :     return to_copy;
     127                 :             : 
     128                 :          77 :   if (buf)
     129                 :          62 :     buf_in_chars = (char *) buf;
     130                 :             :   else
     131                 :          15 :     buf_in_chars = (char *) *alloc_buf;
     132                 :             : 
     133                 :          77 :   if (to_copy >= 2 && buf_in_chars[to_copy - 2] == 0 &&
     134                 :          34 :       buf_in_chars[to_copy - 1] == 0)
     135                 :             :     {
     136                 :             :       /* Fully NUL-terminated, do nothing */
     137                 :          19 :     }
     138                 :          58 :   else if ((to_copy == 1 || buf_in_chars[to_copy - 2] != 0) &&
     139                 :          58 :            buf_in_chars[to_copy - 1] == 0)
     140                 :             :     {
     141                 :             :       /* Have one zero, try to add another one */
     142                 :          32 :       if (extra_bytes > 0)
     143                 :             :         {
     144                 :             :           /* Append trailing zero */
     145                 :          19 :           buf_in_chars[to_copy] = 0;
     146                 :             :           /* Be precise about the number of bytes we return */
     147                 :          19 :           to_copy += 1;
     148                 :          19 :         }
     149                 :          13 :       else if (to_copy >= 2)
     150                 :             :         {
     151                 :             :           /* No space for appending, destroy one byte */
     152                 :          13 :           buf_in_chars[to_copy - 2] = 0;
     153                 :          13 :         }
     154                 :             :       /* else there's no space at all (to_copy == 1), do nothing */
     155                 :          32 :     }
     156                 :          26 :   else if (extra_bytes > 0 || to_copy >= 2)
     157                 :             :     {
     158                 :          18 :       buf_in_chars[to_copy - 2 + extra_bytes] = 0;
     159                 :          18 :       buf_in_chars[to_copy - 1 + extra_bytes] = 0;
     160                 :          18 :       to_copy += extra_bytes;
     161                 :          18 :     }
     162                 :             :   else /* extra_bytes == 0 && to_copy == 1 */
     163                 :             :     {
     164                 :           8 :       buf_in_chars[0] = 0;
     165                 :             :     }
     166                 :             : 
     167                 :          77 :   return to_copy;
     168                 :         156 : }
        

Generated by: LCOV version 2.0-1