@@ -317,6 +317,163 @@ class SimpleClassFuzzTests {
317317}
318318```
319319
320+ ## @ValuePool : Guide fuzzing with custom values
321+
322+ The ` @ValuePool ` annotation lets you provide concrete example values that Jazzer's mutators will use when generating test inputs.
323+ This helps guide fuzzing toward realistic or edge-case values relevant to your application.
324+
325+ ### Basic Usage
326+
327+ You can apply ` @ValuePool ` in two places:
328+ - ** On method parameters** - values apply only to that parameter's type
329+ - ** On the test method itself** - values propagate to all matching types across all parameters
330+
331+ ** Example:**
332+ ``` java
333+ @FuzzTest
334+ void fuzzTest(@ValuePool (value = {" mySupplier" }) Map foo) {
335+ // Strings from mySupplier feed the Map's String mutator
336+ // Integers from mySupplier feed the Map's Integer mutator
337+ }
338+
339+ @FuzzTest
340+ @ValuePool (value = {" mySupplier" })
341+ void anotherFuzzTest(Map foo, String bar) {
342+ // Values propagate to ALL matching types:
343+ // - String mutator for Map keys in 'foo'
344+ // - String mutator for 'bar'
345+ // - Integer mutator for Map values in 'foo'
346+ }
347+
348+ static Stream mySupplier() {
349+ return Stream . of(" example1" , " example2" , " example3" , 1232187321 , - 182371 );
350+ }
351+ ```
352+
353+ ### How Type Matching Works
354+
355+ Jazzer automatically routes values to mutators based on type:
356+ - Strings in your value pool → String mutators
357+ - Integers in your value pool → Integer mutators
358+ - Byte arrays in your value pool → byte[ ] mutators
359+
360+ ** Type propagation happens recursively by default** , so a ` @ValuePool ` on a ` Map<String, Integer> ` will feed both the String mutator (for keys) and Integer mutator (for values).
361+
362+ ---
363+
364+ ### Supplying Values: Two Mechanisms
365+
366+ #### 1. Supplier Methods (` value ` field)
367+
368+ Provide the names of static methods that return ` Stream<?> ` :
369+ ``` java
370+ @ValuePool (value = {" mySupplier" , " anotherSupplier" })
371+ ```
372+
373+ ** Requirements:**
374+ - Methods must be ` static `
375+ - Must return ` Stream<?> `
376+ - Can contain mixed types (Jazzer routes by type automatically)
377+
378+ #### 2. File Patterns (` files ` field)
379+
380+ Load files as ` byte[] ` arrays using glob patterns:
381+ ``` java
382+ @ValuePool (files = {" *.jpeg" }) // All JPEGs in working dir
383+ @ValuePool (files = {" **.xml" }) // All XMLs recursively
384+ @ValuePool (files = {" /absolute/path/**" }) // All files from absolute path
385+ @ValuePool (files = {" *.jpg" , " **.png" }) // Multiple patterns
386+ ```
387+
388+ ** Glob syntax:** Follows ` java.nio.file.PathMatcher ` with ` glob: ` pattern rules.
389+
390+ ** You can combine both mechanisms:**
391+ ``` java
392+ @ValuePool (value = {" mySupplier" }, files = {" test-data/*.json" })
393+ ```
394+
395+ ---
396+
397+ ### Configuration Options
398+
399+ #### Mutation Probability (` p ` field)
400+ Controls how often values from the pool are used versus randomly generated values.
401+ ``` java
402+ @ValuePool (value = {" mySupplier" }, p = 0.3 ) // Use pool values 30% of the time
403+ ```
404+
405+ ** Default:** ` p = 0.1 ` (10% of mutations use pool values)
406+ ** Range:** 0.0 to 1.0
407+
408+ #### Type Propagation (` constraint ` field)
409+
410+ Controls whether the annotation affects nested types:
411+ ``` java
412+ // Default: RECURSIVE - applies to all nested types
413+ @ValuePool (value = {" mySupplier" }, constraint = Constraint . RECURSIVE )
414+
415+ // DECLARATION - applies only to the annotated type, not subtypes
416+ @ValuePool (value = {" mySupplier" }, constraint = Constraint . DECLARATION )
417+ ```
418+
419+ ** Example of the difference:**
420+ ``` java
421+ // With RECURSIVE (default):
422+ @ValuePool (value = {" stringSupplier" }) Map > data
423+ // Strings feed both Map keys AND List elements
424+
425+ // With DECLARATION:
426+ @ValuePool (value = {" stringSupplier" }, constraint = DECLARATION ) Map > data
427+ // Strings only feed Map keys, NOT List elements
428+ ```
429+
430+ ---
431+
432+ ### Complete Example
433+ ``` java
434+ class MyFuzzTest {
435+ static Stream edgeCases () {
436+ return Stream . of(
437+ " " , " null" , " alert('xss')" , // Strings
438+ 0 , - 1 , Integer . MAX_VALUE , // Integers
439+ new byte []{0x00 , 0xFF } // A byte array
440+ );
441+ }
442+
443+ @FuzzTest
444+ @ValuePool (
445+ value = {" edgeCases" },
446+ files = {" test-inputs/*.bin" },
447+ p = 0.25 // Use pool values 25% of the time
448+ )
449+ void testParser (String input , Map config , byte [] data ) {
450+ // All three parameters get values from the pool:
451+ // - 'input' gets Strings
452+ // - 'config' keys get Strings, values get Integers
453+ // - 'data' gets bytes from both edgeCases() and *.bin files
454+ }
455+ }
456+ ```
457+
458+ ---
459+
460+ #### Max Mutations (` maxMutations ` field)
461+
462+ After selecting a value from the pool, the mutator can apply additional random mutations to it.
463+ ``` java
464+ @ValuePool (value = {" mySupplier" }, maxMutations = 5 )
465+ ```
466+
467+ ** Default:** ` maxMutations = 1 ` (one additional mutation applied)
468+ ** Range:** 0 or higher
469+
470+ ** How it works:** If ` maxMutations = 5 ` , Jazzer will:
471+ 1 . Select a value from your pool (e.g., ` "example" ` )
472+ 2 . Apply up to 5 random mutations (e.g., ` "example" ` → ` "exAmple" ` → ` "exAmple123" ` → ...)
473+
474+ This helps explore variations of your seed values while staying close to realistic inputs.
475+
476+
320477## FuzzedDataProvider
321478
322479The ` FuzzedDataProvider ` is an alternative approach commonly used in programming
0 commit comments