}
}
*(to++) = *(from++);
+
/* fix the 4th "char* apple" pointer (aka. executable path pointer) */
*(to++) = *(from++);
+
+#if DARWIN_VERS < DARWIN_12_00
+ /* We only do this on older versions of darwin because dyld changed
+ and by the point we do this changes, the apple env ptr is already set,
+ so if we move values around, we'll end up with a pointer pointing inside
+ (and even potentially after) applep.
+
+ Instead we copy the first value of the applelp over and over again
+ so that envp and applep are still separated by NULL,
+ applep is continuous and points to a correct value.
+
+ See the following example, using the following envp and applep:
+
+ ```
+ 0xXXXX00: PATH=/bin (envp)
+ 0xXXXX08: DYLD_INSERT_LIBRARIES=/lib
+ 0xXXXX10: USER=foo
+ 0xXXXX18: NULL
+ 0xXXXX20: executable_path=/bin/ls (applep)
+ 0xXXXX28: NULL
+ ```
+
+ # With this line
+
+ ```
+ 0xXXXX00: PATH=/bin (envp)
+ 0xXXXX08: USER=foo
+ 0xXXXX10: NULL
+ 0xXXXX18: executable_path=/bin/ls
+ 0xXXXX20: NULL (applep)
+ 0xXXXX28: NULL
+ ```
+
+ Notice that the applep is now invalid.
+
+ # Without this line
+
+ ```
+ 0xXXXX00: PATH=/bin (envp)
+ 0xXXXX08: USER=foo
+ 0xXXXX10: NULL
+ 0xXXXX18: executable_path=/bin/ls
+ 0xXXXX20: executable_path=/bin/ls (applep)
+ 0xXXXX28: NULL
+ ```
+
+ Notice that while values in applep are duplicated, this is only the case if browsing frop envp[len+1]
+ but not from applep which is always valid. Duplicated values are also harmless in this case.
+ */
*to = NULL;
+#endif
}
static void vg_cleanup_env(void) __attribute__((constructor));