MightyPork

str_replace segfault

Mar 25th, 2014
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.60 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. /*
  6. * Replace occurences in input string.
  7. *
  8. * Returned string is alloc'd and the caller has the
  9. * responsibility to clean it up.
  10. */
  11. char* str_replace(const char *src, const char *from, const char *to) {
  12.    
  13.     // helper pointers
  14.     const char *sp; // src pointer
  15.     char *dp; // dest pointer
  16.     const char *mp; // match pointer
  17.    
  18.     // lengths
  19.     size_t from_len = strlen(from);
  20.     size_t to_len = strlen(to);
  21.     size_t src_len = strlen(src);
  22.    
  23.     // count matches
  24.     size_t count = 0;
  25.     sp = src;
  26.     while(1) {
  27.         mp = strstr(sp, from); // find next match
  28.         if(mp == NULL) break; // end of matches
  29.         count++;
  30.         sp = mp + from_len; // advance past match
  31.     }
  32.    
  33.     // compute dest size
  34.     size_t len = src_len;
  35.     size_t sub = (from_len - to_len)*count;
  36.     // sanity check
  37.     if(from_len >= to_len) {
  38.         if(sub > len || sub < 0) return NULL; // integer overflow / bad arith
  39.     } else {
  40.         if((len-sub) < 0 || sub > 0) return NULL; // integer overflow / underflow
  41.     }
  42.    
  43.     // allocate output buffer
  44.     char *dest = malloc( len - sub + 1 );
  45.    
  46.     // fill output buffer
  47.     if(dest != NULL) {
  48.        
  49.         sp = src; // src pointer
  50.         dp = dest; // dest pointer
  51.        
  52.         while(1) {
  53.             mp = strstr(sp, from); // find next match
  54.             if(mp == NULL) break; // end of matches
  55.            
  56.             // copy chunk before match
  57.             memcpy(dp, sp, sp - mp);
  58.             dp += sp-mp;
  59.            
  60.             // copy replacement
  61.             memcpy(dp, to, to_len);
  62.             dp += to_len;
  63.            
  64.             sp = mp + from_len;
  65.         }
  66.        
  67.         // add in the remainder
  68.         if(sp < src + src_len) {
  69.             memcpy(dp, sp, (src + src_len) - sp);
  70.         }
  71.     }
  72.    
  73.     return dest;
  74. }
Advertisement
Add Comment
Please, Sign In to add comment