Commit da6d9a9f2a25ac5c69e8447033715e3d9a89045f

Sam Lantinga 2014-06-04T10:56:56

Added annotations to help code analysis tools CR: Bruce Dawson

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
diff --git a/include/SDL_error.h b/include/SDL_error.h
index 5776cfa..001abb0 100644
--- a/include/SDL_error.h
+++ b/include/SDL_error.h
@@ -38,7 +38,7 @@ extern "C" {
 
 /* Public functions */
 /* SDL_SetError() unconditionally returns -1. */
-extern DECLSPEC int SDLCALL SDL_SetError(const char *fmt, ...);
+extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
 extern DECLSPEC const char *SDLCALL SDL_GetError(void);
 extern DECLSPEC void SDLCALL SDL_ClearError(void);
 
diff --git a/include/SDL_log.h b/include/SDL_log.h
index 5c2bca5..ef4d443 100644
--- a/include/SDL_log.h
+++ b/include/SDL_log.h
@@ -137,44 +137,44 @@ extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void);
 /**
  *  \brief Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO
  */
-extern DECLSPEC void SDLCALL SDL_Log(const char *fmt, ...);
+extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
 
 /**
  *  \brief Log a message with SDL_LOG_PRIORITY_VERBOSE
  */
-extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, const char *fmt, ...);
+extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  *  \brief Log a message with SDL_LOG_PRIORITY_DEBUG
  */
-extern DECLSPEC void SDLCALL SDL_LogDebug(int category, const char *fmt, ...);
+extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  *  \brief Log a message with SDL_LOG_PRIORITY_INFO
  */
-extern DECLSPEC void SDLCALL SDL_LogInfo(int category, const char *fmt, ...);
+extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  *  \brief Log a message with SDL_LOG_PRIORITY_WARN
  */
-extern DECLSPEC void SDLCALL SDL_LogWarn(int category, const char *fmt, ...);
+extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  *  \brief Log a message with SDL_LOG_PRIORITY_ERROR
  */
-extern DECLSPEC void SDLCALL SDL_LogError(int category, const char *fmt, ...);
+extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  *  \brief Log a message with SDL_LOG_PRIORITY_CRITICAL
  */
-extern DECLSPEC void SDLCALL SDL_LogCritical(int category, const char *fmt, ...);
+extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  *  \brief Log a message with the specified category and priority.
  */
 extern DECLSPEC void SDLCALL SDL_LogMessage(int category,
                                             SDL_LogPriority priority,
-                                            const char *fmt, ...);
+                                            SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3);
 
 /**
  *  \brief Log a message with the specified category and priority.
diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h
index 31b343d..9c79ca5 100644
--- a/include/SDL_stdinc.h
+++ b/include/SDL_stdinc.h
@@ -166,6 +166,50 @@ typedef uint64_t Uint64;
 /* @} *//* Basic data types */
 
 
+/* Annotations to help code analysis tools */
+#ifdef SDL_DISABLE_ANALYZE_MACROS
+#define SDL_IN_BYTECAP(x)
+#define SDL_INOUT_Z_CAP(x)
+#define SDL_OUT_Z_CAP(x)
+#define SDL_OUT_CAP(x)
+#define SDL_OUT_BYTECAP(x)
+#define SDL_OUT_Z_BYTECAP(x)
+#define SDL_PRINTF_FORMAT_STRING
+#define SDL_SCANF_FORMAT_STRING
+#define SDL_PRINTF_VARARG_FUNC( fmtargnumber )
+#define SDL_SCANF_VARARG_FUNC( fmtargnumber )
+#else
+#if _MSC_VER >= 1600 /* VS 2010 and above */
+#include <sal.h>
+
+#define SDL_IN_BYTECAP(x) _In_bytecount_(x)
+#define SDL_INOUT_Z_CAP(x) _Inout_z_cap_(x)
+#define SDL_OUT_Z_CAP(x) _Out_z_cap_(x)
+#define SDL_OUT_CAP(x) _Out_cap_(x)
+#define SDL_OUT_BYTECAP(x) _Out_bytecap_(x)
+#define SDL_OUT_Z_BYTECAP(x) _Out_z_bytecap_(x)
+
+#define SDL_PRINTF_FORMAT_STRING _Printf_format_string_
+#define SDL_SCANF_FORMAT_STRING _Scanf_format_string_impl_
+#else
+#define SDL_IN_BYTECAP(x)
+#define SDL_INOUT_Z_CAP(x)
+#define SDL_OUT_Z_CAP(x)
+#define SDL_OUT_CAP(x)
+#define SDL_OUT_BYTECAP(x)
+#define SDL_OUT_Z_BYTECAP(x)
+#define SDL_PRINTF_FORMAT_STRING
+#define SDL_SCANF_FORMAT_STRING
+#endif
+#if defined(__GNUC__)
+#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 )))
+#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 )))
+#else
+#define SDL_PRINTF_VARARG_FUNC( fmtargnumber )
+#define SDL_SCANF_VARARG_FUNC( fmtargnumber )
+#endif
+#endif /* SDL_DISABLE_ANALYSE_MACROS */
+
 #define SDL_COMPILE_TIME_ASSERT(name, x)               \
        typedef int SDL_dummy_ ## name[(x) * 2 - 1]
 /** \cond */
@@ -259,7 +303,7 @@ extern DECLSPEC int SDLCALL SDL_isspace(int x);
 extern DECLSPEC int SDLCALL SDL_toupper(int x);
 extern DECLSPEC int SDLCALL SDL_tolower(int x);
 
-extern DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len);
+extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len);
 
 #define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x)))
 #define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x)))
@@ -294,24 +338,24 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
 }
 
 
-extern DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len);
+extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 
-SDL_FORCE_INLINE void *SDL_memcpy4(void *dst, const void *src, size_t dwords)
+SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords)
 {
     return SDL_memcpy(dst, src, dwords * 4);
 }
 
-extern DECLSPEC void *SDLCALL SDL_memmove(void *dst, const void *src, size_t len);
+extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
 
 extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
-extern DECLSPEC size_t SDLCALL SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen);
-extern DECLSPEC size_t SDLCALL SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen);
+extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
+extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
 
 extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str);
-extern DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen);
-extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes);
-extern DECLSPEC size_t SDLCALL SDL_strlcat(char *dst, const char *src, size_t maxlen);
+extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen);
+extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes);
+extern DECLSPEC size_t SDLCALL SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen);
 extern DECLSPEC char *SDLCALL SDL_strdup(const char *str);
 extern DECLSPEC char *SDLCALL SDL_strrev(char *str);
 extern DECLSPEC char *SDLCALL SDL_strupr(char *str);
@@ -340,10 +384,10 @@ extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size
 extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2);
 extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len);
 
-extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt, ...);
+extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2);
 extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap);
-extern DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...);
-extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap);
+extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3);
+extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap);
 
 #ifndef HAVE_M_PI
 #ifndef M_PI
diff --git a/include/SDL_test_assert.h b/include/SDL_test_assert.h
index 79c84d6..5b38f7e 100644
--- a/include/SDL_test_assert.h
+++ b/include/SDL_test_assert.h
@@ -58,7 +58,7 @@ extern "C" {
  * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0).
  * \param assertDescription Message to log with the assert describing it.
  */
-void SDLTest_Assert(int assertCondition, const char *assertDescription, ...);
+void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  * \brief Assert for test cases that logs but does not break execution flow on failures. Updates assertion counters.
@@ -68,14 +68,14 @@ void SDLTest_Assert(int assertCondition, const char *assertDescription, ...);
  *
  * \returns Returns the assertCondition so it can be used to externally to break execution flow if desired.
  */
-int SDLTest_AssertCheck(int assertCondition, const char *assertDescription, ...);
+int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2);
 
 /**
  * \brief Explicitely pass without checking an assertion condition. Updates assertion counter.
  *
  * \param assertDescription Message to log with the assert describing it.
  */
-void SDLTest_AssertPass(const char *assertDescription, ...);
+void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(1);
 
 /**
  * \brief Resets the assert summary counters to zero.
diff --git a/include/SDL_test_log.h b/include/SDL_test_log.h
index 76ce105..2157954 100644
--- a/include/SDL_test_log.h
+++ b/include/SDL_test_log.h
@@ -47,14 +47,14 @@ extern "C" {
  *
  * \param fmt Message to be logged
  */
-void SDLTest_Log(const char *fmt, ...);
+void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
 
 /**
  * \brief Prints given message with a timestamp in the TEST category and the ERROR priority.
  *
  * \param fmt Message to be logged
  */
-void SDLTest_LogError(const char *fmt, ...);
+void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/src/SDL_error.c b/src/SDL_error.c
index ecbf450..2df29aa 100644
--- a/src/SDL_error.c
+++ b/src/SDL_error.c
@@ -50,7 +50,7 @@ SDL_LookupString(const char *key)
 /* Public functions */
 
 int
-SDL_SetError(const char *fmt, ...)
+SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
     SDL_error *error;
diff --git a/src/SDL_log.c b/src/SDL_log.c
index 39aa3e4..56d0b42 100644
--- a/src/SDL_log.c
+++ b/src/SDL_log.c
@@ -26,6 +26,7 @@
 
 /* Simple log messages in SDL */
 
+#include "SDL_error.h"
 #include "SDL_log.h"
 
 #if HAVE_STDIO_H
@@ -41,9 +42,6 @@
 #define DEFAULT_APPLICATION_PRIORITY    SDL_LOG_PRIORITY_INFO
 #define DEFAULT_TEST_PRIORITY           SDL_LOG_PRIORITY_VERBOSE
 
-/* Forward definition of error function */
-extern int SDL_SetError(const char *fmt, ...);
-
 typedef struct SDL_LogLevel
 {
     int category;
@@ -172,7 +170,7 @@ SDL_LogResetPriorities(void)
 }
 
 void
-SDL_Log(const char *fmt, ...)
+SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
@@ -182,7 +180,7 @@ SDL_Log(const char *fmt, ...)
 }
 
 void
-SDL_LogVerbose(int category, const char *fmt, ...)
+SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
@@ -192,7 +190,7 @@ SDL_LogVerbose(int category, const char *fmt, ...)
 }
 
 void
-SDL_LogDebug(int category, const char *fmt, ...)
+SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
@@ -202,7 +200,7 @@ SDL_LogDebug(int category, const char *fmt, ...)
 }
 
 void
-SDL_LogInfo(int category, const char *fmt, ...)
+SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
@@ -212,7 +210,7 @@ SDL_LogInfo(int category, const char *fmt, ...)
 }
 
 void
-SDL_LogWarn(int category, const char *fmt, ...)
+SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
@@ -222,7 +220,7 @@ SDL_LogWarn(int category, const char *fmt, ...)
 }
 
 void
-SDL_LogError(int category, const char *fmt, ...)
+SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
@@ -232,7 +230,7 @@ SDL_LogError(int category, const char *fmt, ...)
 }
 
 void
-SDL_LogCritical(int category, const char *fmt, ...)
+SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
@@ -242,7 +240,7 @@ SDL_LogCritical(int category, const char *fmt, ...)
 }
 
 void
-SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...)
+SDL_LogMessage(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
 
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index 903264c..8daa8c6 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -493,8 +493,7 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc,
         IMA_ADPCM_encoded = 1;
         break;
     case MP3_CODE:
-        SDL_SetError("MPEG Layer 3 data not supported",
-                     SDL_SwapLE16(format->encoding));
+        SDL_SetError("MPEG Layer 3 data not supported");
         was_error = 1;
         goto done;
     default:
diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c
index 220ec9b..c378699 100644
--- a/src/dynapi/SDL_dynapi.c
+++ b/src/dynapi/SDL_dynapi.c
@@ -56,38 +56,38 @@ static void SDL_InitDynamicAPI(void);
 #if DISABLE_JUMP_MAGIC
 /* Can't use the macro for varargs nonsense. This is atrocious. */
 #define SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, logname, prio) \
-    _static void SDL_Log##logname##name(int category, const char *fmt, ...) { \
+    _static void SDL_Log##logname##name(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
         va_list ap; initcall; va_start(ap, fmt); \
         jump_table.SDL_LogMessageV(category, SDL_LOG_PRIORITY_##prio, fmt, ap); \
         va_end(ap); \
     }
 
 #define SDL_DYNAPI_VARARGS(_static, name, initcall) \
-    _static int SDL_SetError##name(const char *fmt, ...) { \
+    _static int SDL_SetError##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
         char buf[512]; /* !!! FIXME: dynamic allocation */ \
         va_list ap; initcall; va_start(ap, fmt); \
         jump_table.SDL_vsnprintf(buf, sizeof (buf), fmt, ap); \
         va_end(ap); \
         return jump_table.SDL_SetError("%s", buf); \
     } \
-    _static int SDL_sscanf##name(const char *buf, const char *fmt, ...) { \
+    _static int SDL_sscanf##name(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...) { \
         int retval; va_list ap; initcall; va_start(ap, fmt); \
         retval = jump_table.SDL_vsscanf(buf, fmt, ap); \
         va_end(ap); \
         return retval; \
     } \
-    _static int SDL_snprintf##name(char *buf, size_t buflen, const char *fmt, ...) { \
+    _static int SDL_snprintf##name(SDL_OUT_Z_CAP(maxlen) char *buf, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
         int retval; va_list ap; initcall; va_start(ap, fmt); \
-        retval = jump_table.SDL_vsnprintf(buf, buflen, fmt, ap); \
+        retval = jump_table.SDL_vsnprintf(buf, maxlen, fmt, ap); \
         va_end(ap); \
         return retval; \
     } \
-    _static void SDL_Log##name(const char *fmt, ...) { \
+    _static void SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
         va_list ap; initcall; va_start(ap, fmt); \
         jump_table.SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); \
         va_end(ap); \
     } \
-    _static void SDL_LogMessage##name(int category, SDL_LogPriority priority, const char *fmt, ...) { \
+    _static void SDL_LogMessage##name(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
         va_list ap; initcall; va_start(ap, fmt); \
         jump_table.SDL_LogMessageV(category, priority, fmt, ap); \
         va_end(ap); \
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index d39b19a..44b9fd2 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -31,17 +31,17 @@
 
 /* direct jump magic can use these, the rest needs special code. */
 #if !SDL_DYNAPI_PROC_NO_VARARGS
-SDL_DYNAPI_PROC(int,SDL_SetError,(const char *a, ...),(a),return)
-SDL_DYNAPI_PROC(void,SDL_Log,(const char *a, ...),(a),)
-SDL_DYNAPI_PROC(void,SDL_LogVerbose,(int a, const char *b, ...),(a,b),)
-SDL_DYNAPI_PROC(void,SDL_LogDebug,(int a, const char *b, ...),(a,b),)
-SDL_DYNAPI_PROC(void,SDL_LogInfo,(int a, const char *b, ...),(a,b),)
-SDL_DYNAPI_PROC(void,SDL_LogWarn,(int a, const char *b, ...),(a,b),)
-SDL_DYNAPI_PROC(void,SDL_LogError,(int a, const char *b, ...),(a,b),)
-SDL_DYNAPI_PROC(void,SDL_LogCritical,(int a, const char *b, ...),(a,b),)
-SDL_DYNAPI_PROC(void,SDL_LogMessage,(int a, SDL_LogPriority b, const char *c, ...),(a,b,c),)
-SDL_DYNAPI_PROC(int,SDL_sscanf,(const char *a, const char *b, ...),(a,b),return)
-SDL_DYNAPI_PROC(int,SDL_snprintf,(char *a, size_t b, const char *c, ...),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_SetError,(SDL_PRINTF_FORMAT_STRING const char *a, ...),(a),return)
+SDL_DYNAPI_PROC(void,SDL_Log,(SDL_PRINTF_FORMAT_STRING const char *a, ...),(a),)
+SDL_DYNAPI_PROC(void,SDL_LogVerbose,(int a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),)
+SDL_DYNAPI_PROC(void,SDL_LogDebug,(int a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),)
+SDL_DYNAPI_PROC(void,SDL_LogInfo,(int a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),)
+SDL_DYNAPI_PROC(void,SDL_LogWarn,(int a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),)
+SDL_DYNAPI_PROC(void,SDL_LogError,(int a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),)
+SDL_DYNAPI_PROC(void,SDL_LogCritical,(int a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),)
+SDL_DYNAPI_PROC(void,SDL_LogMessage,(int a, SDL_LogPriority b, SDL_PRINTF_FORMAT_STRING const char *c, ...),(a,b,c),)
+SDL_DYNAPI_PROC(int,SDL_sscanf,(const char *a, SDL_SCANF_FORMAT_STRING const char *b, ...),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_snprintf,(SDL_OUT_Z_CAP(b) char *a, size_t b, SDL_PRINTF_FORMAT_STRING const char *c, ...),(a,b,c),return)
 #endif
 
 #ifdef SDL_CreateThread
@@ -418,17 +418,17 @@ SDL_DYNAPI_PROC(int,SDL_isdigit,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_isspace,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_toupper,(int a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_tolower,(int a),(a),return)
-SDL_DYNAPI_PROC(void*,SDL_memset,(void *a, int b, size_t c),(a,b,c),return)
-SDL_DYNAPI_PROC(void*,SDL_memcpy,(void *a, const void *b, size_t c),(a,b,c),return)
-SDL_DYNAPI_PROC(void*,SDL_memmove,(void *a, const void *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(void*,SDL_memset,(SDL_OUT_BYTECAP(c) void *a, int b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(void*,SDL_memcpy,(SDL_OUT_BYTECAP(c) void *a, SDL_IN_BYTECAP(c) const void *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(void*,SDL_memmove,(SDL_OUT_BYTECAP(c) void *a, SDL_IN_BYTECAP(c) const void *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_memcmp,(const void *a, const void *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(size_t,SDL_wcslen,(const wchar_t *a),(a),return)
-SDL_DYNAPI_PROC(size_t,SDL_wcslcpy,(wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
-SDL_DYNAPI_PROC(size_t,SDL_wcslcat,(wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(size_t,SDL_wcslcpy,(SDL_OUT_Z_CAP(c) wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(size_t,SDL_wcslcat,(SDL_INOUT_Z_CAP(c) wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(size_t,SDL_strlen,(const char *a),(a),return)
-SDL_DYNAPI_PROC(size_t,SDL_strlcpy,(char *a, const char *b, size_t c),(a,b,c),return)
-SDL_DYNAPI_PROC(size_t,SDL_utf8strlcpy,(char *a, const char *b, size_t c),(a,b,c),return)
-SDL_DYNAPI_PROC(size_t,SDL_strlcat,(char *a, const char *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(size_t,SDL_strlcpy,(SDL_OUT_Z_CAP(c) char *a, const char *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(size_t,SDL_utf8strlcpy,(SDL_OUT_Z_CAP(c) char *a, const char *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(size_t,SDL_strlcat,(SDL_INOUT_Z_CAP(c) char *a, const char *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(char*,SDL_strdup,(const char *a),(a),return)
 SDL_DYNAPI_PROC(char*,SDL_strrev,(char *a),(a),return)
 SDL_DYNAPI_PROC(char*,SDL_strupr,(char *a),(a),return)
@@ -453,7 +453,7 @@ SDL_DYNAPI_PROC(int,SDL_strcmp,(const char *a, const char *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_strncmp,(const char *a, const char *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_strcasecmp,(const char *a, const char *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_strncasecmp,(const char *a, const char *b, size_t c),(a,b,c),return)
-SDL_DYNAPI_PROC(int,SDL_vsnprintf,(char *a, size_t b, const char *c, va_list d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(int,SDL_vsnprintf,(SDL_OUT_Z_CAP(b) char *a, size_t b, const char *c, va_list d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(double,SDL_acos,(double a),(a),return)
 SDL_DYNAPI_PROC(double,SDL_asin,(double a),(a),return)
 SDL_DYNAPI_PROC(double,SDL_atan,(double a),(a),return)
diff --git a/src/joystick/windows/SDL_dxjoystick.c b/src/joystick/windows/SDL_dxjoystick.c
index cd8fad0..66c2e0f 100644
--- a/src/joystick/windows/SDL_dxjoystick.c
+++ b/src/joystick/windows/SDL_dxjoystick.c
@@ -45,6 +45,7 @@
 #if !SDL_EVENTS_DISABLED
 #include "../../events/SDL_events_c.h"
 #endif
+#include "../../core/windows/SDL_windows.h"
 
 #define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
 #include "SDL_dxjoystick_c.h"
@@ -499,13 +500,13 @@ SDL_JoystickThread(void *_data)
 
     if (!RegisterClassEx (&wincl))
     {
-        return SDL_SetError("Failed to create register class for joystick autodetect.", GetLastError());
+		return WIN_SetError( "Failed to create register class for joystick autodetect");
     }
 
     messageWindow = (HWND)CreateWindowEx( 0,  L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
     if ( !messageWindow )
     {
-        return SDL_SetError("Failed to create message window for joystick autodetect.", GetLastError());
+        return WIN_SetError("Failed to create message window for joystick autodetect");
     }
 
     SDL_zero(dbh);
@@ -517,7 +518,7 @@ SDL_JoystickThread(void *_data)
     hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE );
     if ( !hNotify )
     {
-        return SDL_SetError("Failed to create notify device for joystick autodetect.", GetLastError());
+		return WIN_SetError( "Failed to create notify device for joystick autodetect");
     }
 
     SDL_LockMutex( s_mutexJoyStickEnum );
diff --git a/src/power/SDL_power.c b/src/power/SDL_power.c
index 10f8355..cc9ba39 100644
--- a/src/power/SDL_power.c
+++ b/src/power/SDL_power.c
@@ -93,7 +93,7 @@ SDL_GetPowerInfo(int *seconds, int *percent)
 {
     const int total = sizeof(implementations) / sizeof(implementations[0]);
     int _seconds, _percent;
-    SDL_PowerState retval;
+    SDL_PowerState retval = SDL_POWERSTATE_UNKNOWN;
     int i;
 
     /* Make these never NULL for platform-specific implementations. */
@@ -106,7 +106,7 @@ SDL_GetPowerInfo(int *seconds, int *percent)
     }
 
     for (i = 0; i < total; i++) {
-        if (implementations[i] (&retval, seconds, percent)) {
+        if (implementations[i](&retval, seconds, percent)) {
             return retval;
         }
     }
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index a9ca267..733a257 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -258,7 +258,7 @@ SDL_ScanFloat(const char *text, double *valuep)
 #endif
 
 void *
-SDL_memset(void *dst, int c, size_t len)
+SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len)
 {
 #if defined(HAVE_MEMSET)
     return memset(dst, c, len);
@@ -302,7 +302,7 @@ SDL_memset(void *dst, int c, size_t len)
 }
 
 void *
-SDL_memcpy(void *dst, const void *src, size_t len)
+SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len)
 {
 #ifdef __GNUC__
     /* Presumably this is well tuned for speed.
@@ -355,7 +355,7 @@ SDL_memcpy(void *dst, const void *src, size_t len)
 }
 
 void *
-SDL_memmove(void *dst, const void *src, size_t len)
+SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len)
 {
 #if defined(HAVE_MEMMOVE)
     return memmove(dst, src, len);
@@ -426,7 +426,7 @@ SDL_wcslen(const wchar_t * string)
 }
 
 size_t
-SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
+SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen)
 {
 #if defined(HAVE_WCSLCPY)
     return wcslcpy(dst, src, maxlen);
@@ -442,7 +442,7 @@ SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
 }
 
 size_t
-SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
+SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen)
 {
 #if defined(HAVE_WCSLCAT)
     return wcslcat(dst, src, maxlen);
@@ -457,7 +457,7 @@ SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
 }
 
 size_t
-SDL_strlcpy(char *dst, const char *src, size_t maxlen)
+SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen)
 {
 #if defined(HAVE_STRLCPY)
     return strlcpy(dst, src, maxlen);
@@ -472,7 +472,7 @@ SDL_strlcpy(char *dst, const char *src, size_t maxlen)
 #endif /* HAVE_STRLCPY */
 }
 
-size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
+size_t SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes)
 {
     size_t src_bytes = SDL_strlen(src);
     size_t bytes = SDL_min(src_bytes, dst_bytes - 1);
@@ -505,7 +505,7 @@ size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
 }
 
 size_t
-SDL_strlcat(char *dst, const char *src, size_t maxlen)
+SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen)
 {
 #if defined(HAVE_STRLCAT)
     return strlcat(dst, src, maxlen);
@@ -980,7 +980,7 @@ SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen)
 }
 
 int
-SDL_sscanf(const char *text, const char *fmt, ...)
+SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...)
 {
     int rc;
     va_list ap;
@@ -1261,7 +1261,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap)
 #endif /* HAVE_VSSCANF */
 
 int
-SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
+SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list ap;
     int retval;
@@ -1274,7 +1274,7 @@ SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
 }
 
 #ifdef HAVE_VSNPRINTF
-int SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap)
+int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap)
 {
     return vsnprintf(text, maxlen, fmt, ap);
 }
@@ -1463,7 +1463,7 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
 }
 
 int
-SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap)
+SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap)
 {
     size_t left = maxlen;
     char *textstart = text;
diff --git a/src/test/SDL_test_assert.c b/src/test/SDL_test_assert.c
index 0a59493..93df3b3 100644
--- a/src/test/SDL_test_assert.c
+++ b/src/test/SDL_test_assert.c
@@ -44,7 +44,7 @@ static Uint32 SDLTest_AssertsPassed = 0;
 /*
  *  Assert that logs and break execution flow on failures (i.e. for harness errors).
  */
-void SDLTest_Assert(int assertCondition, const char *assertDescription, ...)
+void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...)
 {
         va_list list;
     char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
@@ -62,7 +62,7 @@ void SDLTest_Assert(int assertCondition, const char *assertDescription, ...)
 /*
  * Assert that logs but does not break execution flow on failures (i.e. for test cases).
  */
-int SDLTest_AssertCheck(int assertCondition, const char *assertDescription, ...)
+int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...)
 {
     va_list list;
     char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
@@ -91,7 +91,7 @@ int SDLTest_AssertCheck(int assertCondition, const char *assertDescription, ...)
 /*
  * Explicitly passing Assert that logs (i.e. for test cases).
  */
-void SDLTest_AssertPass(const char *assertDescription, ...)
+void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...)
 {
     va_list list;
     char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
diff --git a/src/test/SDL_test_log.c b/src/test/SDL_test_log.c
index 9a08307..6c076aa 100644
--- a/src/test/SDL_test_log.c
+++ b/src/test/SDL_test_log.c
@@ -68,7 +68,7 @@ char *SDLTest_TimestampToString(const time_t timestamp)
 /*
  * Prints given message with a timestamp in the TEST category and INFO priority.
  */
-void SDLTest_Log(const char *fmt, ...)
+void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list list;
     char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
@@ -86,7 +86,7 @@ void SDLTest_Log(const char *fmt, ...)
 /*
  * Prints given message with a timestamp in the TEST category and the ERROR priority.
  */
-void SDLTest_LogError(const char *fmt, ...)
+void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
 {
     va_list list;
     char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 7599e58..c3a2655 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -1093,7 +1093,9 @@ static void
 SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
 {
     SDL_VideoDisplay *display;
-    SDL_Window *other;
+	SDL_Window *other;
+
+	CHECK_WINDOW_MAGIC(window,);
 
 #ifdef __MACOSX__
     if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {