summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMarcus Meissner <marcus@jet.franken.de>2021-09-26 14:03:32 +0200
committerMarcus Meissner <marcus@jet.franken.de>2021-09-26 14:03:32 +0200
commitc0d4de1eca203a4a52df3936e457ac224320354f (patch)
treecab9da2784cd0d8eb49aff1375a3e54c57dbc49b /examples
parent6899d140ecf45a31f5357a14927e8f2f91971961 (diff)
downloadlibgphoto2-c0d4de1eca203a4a52df3936e457ac224320354f.tar.gz
start a sample for libfuzz
Diffstat (limited to 'examples')
-rw-r--r--examples/sample-libfuzz.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/examples/sample-libfuzz.c b/examples/sample-libfuzz.c
new file mode 100644
index 000000000..056340636
--- /dev/null
+++ b/examples/sample-libfuzz.c
@@ -0,0 +1,283 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <gphoto2/gphoto2-camera.h>
+#include <gphoto2/gphoto2-port-log.h>
+
+#include "samples.h"
+
+/* Sample for AFL usage.
+ *
+ */
+
+void errordumper(GPLogLevel level, const char *domain, const char *str,
+ void *data) {
+ /* Do not log ... but let it appear here so we discover debug paths */
+ fprintf(stderr, "%s:%s\n", domain, str);
+}
+
+static int
+recursive_directory(Camera *camera, const char *folder, GPContext *context, int *foundfile) {
+ int i, ret;
+ CameraList *list;
+ const char *newfile;
+ CameraFileInfo fileinfo;
+ CameraFile *file;
+
+ ret = gp_list_new (&list);
+ if (ret < GP_OK) {
+ printf ("Could not allocate list.\n");
+ return ret;
+ }
+
+ ret = gp_camera_folder_list_folders (camera, folder, list, context);
+ if (ret < GP_OK) {
+ printf ("Could not list folders.\n");
+ gp_list_free (list);
+ return ret;
+ }
+ gp_list_sort (list);
+
+ for (i = 0; i < gp_list_count (list); i++) {
+ const char *newfolder;
+ char *buf;
+ int havefile = 0;
+
+ gp_list_get_name (list, i, &newfolder);
+
+ if (!strlen(newfolder)) continue;
+
+ buf = (char*)malloc (strlen(folder) + 1 + strlen(newfolder) + 1);
+ strcpy(buf, folder);
+ if (strcmp(folder,"/")) /* avoid double / */
+ strcat(buf, "/");
+ strcat(buf, newfolder);
+
+ fprintf(stderr,"newfolder=%s\n", newfolder);
+
+ ret = recursive_directory (camera, buf, context, &havefile);
+ free (buf);
+ if (ret != GP_OK) {
+ gp_list_free (list);
+ printf ("Failed to recursively list folders.\n");
+ return ret;
+ }
+ if (havefile) /* only look for the first directory with a file */
+ break;
+ }
+ gp_list_reset (list);
+
+ ret = gp_camera_folder_list_files (camera, folder, list, context);
+ if (ret < GP_OK) {
+ gp_list_free (list);
+ printf ("Could not list files.\n");
+ return ret;
+ }
+ gp_list_sort (list);
+ if (gp_list_count (list) <= 0) {
+ gp_list_free (list);
+ return GP_OK;
+ }
+
+ gp_list_get_name (list, 0, &newfile); /* only entry 0 needed */
+ ret = gp_camera_file_get_info (camera, folder, newfile, &fileinfo, context);
+ if (ret != GP_OK) {
+ gp_list_free (list);
+ printf ("Could not get file info.\n");
+ return ret;
+ }
+
+ /* get file */
+ gp_file_new (&file);
+ ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_NORMAL, file, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ gp_list_free (list);
+ printf ("Could not get file.\n");
+ return ret;
+ }
+ gp_file_unref (file);
+ /* get preview */
+ gp_file_new (&file);
+ ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_PREVIEW, file, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ gp_list_free (list);
+ printf ("Could not get file preview.\n");
+ return ret;
+ }
+ gp_file_unref (file);
+ /* get exif */
+ gp_file_new (&file);
+ ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_EXIF, file, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ gp_list_free (list);
+ printf ("Could not get file preview.\n");
+ return ret;
+ }
+ gp_file_unref (file);
+ /* Trigger the ptp things */
+ gp_file_new (&file);
+ ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_METADATA, file, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ gp_list_free (list);
+ printf ("Could not get file metadata.\n");
+ return ret;
+ }
+ gp_file_unref (file);
+ if (foundfile) *foundfile = 1;
+ gp_list_free (list);
+ return GP_OK;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ static int initialized = 0;
+ Camera *camera = NULL;
+ int ret, storagecnt;
+ CameraStorageInformation *storageinfo;
+
+ GPPortInfo pi;
+ static GPPortInfoList *gpinfolist = NULL;
+ static GPContext *context = NULL;
+ char buf[200];
+ static const char *name;
+ char tmpfn[200];
+
+ int fd;
+ CameraWidget *rootwidget;
+ CameraText summary;
+ CameraFile *file;
+ /*CameraFilePath path;*/
+ CameraList *list;
+ static CameraAbilitiesList *abilities = NULL;
+
+ gp_log_add_func(GP_LOG_DEBUG, errordumper, NULL);
+
+ if (!initialized) {
+ context = sample_create_context (); /* see context.c */
+
+ gp_port_info_list_new (&gpinfolist);
+ ret = gp_port_info_list_load (gpinfolist);
+ if (ret < GP_OK) return 0;
+
+ /* Detect all the cameras that can be autodetected... */
+ ret = gp_list_new (&list);
+ if (ret < GP_OK) return 0;
+
+ /* Load all the camera drivers we have... */
+ ret = gp_abilities_list_new (&abilities);
+ if (ret < GP_OK) return ret;
+ ret = gp_abilities_list_load (abilities, context);
+ if (ret < GP_OK) return ret;
+ ret = gp_abilities_list_detect (abilities, gpinfolist, list, context);
+ if (ret < GP_OK) return ret;
+ /*fprintf(stderr, "detect list has count %d\n", gp_list_count(list));*/
+
+
+ ret = gp_list_get_name(list, 0, &name);
+ if (ret < GP_OK) goto out;
+ gp_list_free (list);
+
+ ret = sample_open_camera (&camera, name, "vusb:", context);
+ if (ret < GP_OK) {
+ fprintf(stderr,"camera %s at %s not found.\n", name, buf);
+ goto out;
+ }
+
+ initialized = 1;
+ }
+ /* code that runs all the time */
+
+ strcpy(tmpfn,"/dev/shm/gphotofuzz.XXXXXX");
+ fd = mkstemp(tmpfn);
+ write (fd, Data, Size);
+ close(fd);
+
+ strcpy(buf,"vusb:");
+ strcat(buf,tmpfn);
+
+ fprintf(stderr,"setting path %s.\n", buf);
+
+ gp_camera_get_port_info (camera, &pi);
+ gp_port_info_set_path (pi, buf);
+ gp_camera_set_port_info (camera, pi);
+
+ ret = gp_camera_init (camera, context);
+ if (ret < GP_OK) {
+ fprintf(stderr,"No camera auto detected.\n");
+ goto out;
+ }
+
+ /* AFL PART STARTS HERE */
+
+ ret = recursive_directory(camera, "/", context, NULL);
+ if (ret < GP_OK) {
+ printf ("Could not recursive list files.\n");
+ goto out;
+ }
+
+ ret = gp_camera_get_summary (camera, &summary, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ printf ("Could not get summary.\n");
+ goto out;
+ }
+
+#if 1
+ ret = gp_camera_get_config (camera, &rootwidget, context);
+ if (ret < GP_OK) {
+ fprintf (stderr,"Could not get config.\n");
+ goto out;
+ }
+ gp_widget_free (rootwidget);
+#endif
+ printf ("OK, %s\n", summary.text);
+
+ ret = gp_camera_get_storageinfo (camera, &storageinfo, &storagecnt, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ printf ("Could not get storage info.\n");
+ goto out;
+ }
+ free(storageinfo);
+
+ ret = gp_camera_trigger_capture (camera, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ printf ("Could not trigger capture.\n");
+ goto out;
+ }
+
+ while (1) {
+ CameraEventType evttype;
+ void *data = NULL;
+
+ ret = gp_camera_wait_for_event(camera, 1, &evttype, &data, context);
+ if (ret < GP_OK) break;
+ if (data) free (data);
+ if (evttype == GP_EVENT_TIMEOUT) break;
+ }
+
+ gp_file_new (&file);
+ ret = gp_camera_capture_preview (camera, file, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ gp_file_free (file);
+ printf ("Could not capture preview.\n");
+ goto out;
+ }
+ gp_file_free (file);
+
+#if 0
+ /* this gives endless event check loops occasionaly ... need review how to do this best */
+ ret = gp_camera_capture (camera, GP_CAPTURE_IMAGE, &path, context);
+ if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
+ printf ("Could not capture preview.\n");
+ goto out;
+ }
+#endif
+
+ /* AFL PART ENDS HERE */
+out:
+ gp_camera_exit (camera, context);
+ /*gp_context_unref (context);*/
+ /*gp_camera_free (camera);*/
+ unlink (tmpfn);
+ return 0;
+}